Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.sys.acorn.programmer > #5921 > unrolled thread
| Started by | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| First post | 2020-01-03 17:16 +0000 |
| Last post | 2020-01-08 12:46 +0000 |
| Articles | 20 on this page of 26 — 9 participants |
Back to article view | Back to comp.sys.acorn.programmer
BASIC oddity? Alan Adams <alan@adamshome.org.uk> - 2020-01-03 17:16 +0000
Re: BASIC oddity? Martin <News03@avisoft.f9.co.uk> - 2020-01-03 19:31 +0000
Re: BASIC oddity? druck <news@druck.org.uk> - 2020-01-03 21:00 +0000
Re: BASIC oddity? Alan Adams <alan@adamshome.org.uk> - 2020-01-03 22:26 +0000
Re: BASIC oddity? Steve Drain <steve@kappa.me.uk> - 2020-01-04 10:40 +0000
Re: BASIC oddity? Martin <News03@avisoft.f9.co.uk> - 2020-01-04 16:08 +0000
Re: BASIC oddity? Alan Adams <alan@adamshome.org.uk> - 2020-01-04 16:22 +0000
Re: BASIC oddity? David Higton <dave@davehigton.me.uk> - 2020-01-04 17:24 +0000
Re: BASIC oddity? Alan Adams <alan@adamshome.org.uk> - 2020-01-04 18:47 +0000
Re: BASIC oddity? Matthew Phillips <spam2011m@yahoo.co.uk> - 2020-01-06 08:58 +0000
Re: BASIC oddity? David Higton <dave@davehigton.me.uk> - 2020-01-06 16:20 +0000
Re: BASIC oddity? Matthew Phillips <spam2011m@yahoo.co.uk> - 2020-01-07 08:49 +0000
Re: BASIC oddity? Martin <News03@avisoft.f9.co.uk> - 2020-01-07 11:20 +0000
Re: BASIC oddity? David Higton <dave@davehigton.me.uk> - 2020-01-07 15:05 +0000
Re: BASIC oddity? Matthew Phillips <spam2011m@yahoo.co.uk> - 2020-01-08 08:23 +0000
Re: BASIC oddity? Alan Adams <alan@adamshome.org.uk> - 2020-01-08 10:26 +0000
Re: BASIC oddity? druck <news@druck.org.uk> - 2020-01-08 21:02 +0000
Re: BASIC oddity? Richard Ashbery <basura@invalid.addr.uk> - 2020-01-09 12:53 +0000
Re: BASIC oddity? Steve Fryatt <news@stevefryatt.org.uk> - 2020-01-09 23:16 +0000
Re: BASIC oddity? Steve Fryatt <news@stevefryatt.org.uk> - 2020-01-08 22:35 +0000
Re: BASIC oddity? Martin <News03@avisoft.f9.co.uk> - 2020-01-08 23:51 +0000
Re: BASIC oddity? Steve Drain <steve@kappa.me.uk> - 2020-01-10 11:30 +0000
Re: BASIC oddity? Alan Adams <alan@adamshome.org.uk> - 2020-01-10 12:38 +0000
Re: BASIC oddity? Jean-Michel <jmc.bruck@orange.fr> - 2020-01-06 20:39 +0100
Re: BASIC oddity? Alan Adams <alan@adamshome.org.uk> - 2020-01-06 21:13 +0000
Re: BASIC oddity? Steve Drain <steve@kappa.me.uk> - 2020-01-08 12:46 +0000
Page 1 of 2 [1] 2 Next page →
| From | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| Date | 2020-01-03 17:16 +0000 |
| Subject | BASIC oddity? |
| Message-ID | <4adaa32c58.Alan.Adams@ArmX6.adamshome.org.uk> |
I've either discovered something odd but useful about BASIC, or I#ve got myself rather confused. The issue arose because I need to subtract one 5-byte time from another, returning the result in an integer. This will obviously fail if the result is too large to fit in an integer, but that is a large number of days, and will not occur in my particular case, as the computers will not need to run that long without a restart. What I thinki I've discovered is that although BASIC treats values that go beyone &7fffffff as negative numbers, when suntracting them one from another it treats them as unsigned. The following example demonstrates why I think this is the case. Note that I'm ignoring the MSB of the 5-byte times, as the test was created to fnd out what I needed to do with it, and seems to show that I simply ignore it. The weird example is the third, where subtracting a very large positive number from a very large negative number produces a positive result. Comments please: REM > TimingTest DEBUG%=1 DIM currentbuf% 5, baseline% 5 !baseline%=&80 ?(baseline%+4)=&58 !currentbuf%=&184 ?(currentbuf%+4)=&58 PRINT FNsubtimes(currentbuf%,baseline%) !baseline%=&7FFFFE00 ?(baseline%+4)=&58 !currentbuf%=&7FFFFF04 ?(currentbuf%+4)=&58 PRINT FNsubtimes(currentbuf%,baseline%) !baseline%=&7FFFFF80 ?(baseline%+4)=&58 !currentbuf%=&80000084 ?(currentbuf%+4)=&50 PRINT FNsubtimes(currentbuf%,baseline%) !baseline%=&FFFFFF80 ?(baseline%+4)=&58 !currentbuf%=&84 ?(currentbuf%+4)=&58 PRINT FNsubtimes(currentbuf%,baseline%) END DEF FNsubtimes(buf1%,buf2%) REM subtract 5-byte time in buf2% from buf1% LOCAL I%,J%,K% PRINT I%=!buf1% J%=!buf2% K%=I%-J% REM IF DEBUG%AND1 THEN *REPORT TL: subtimes: I% J% ~I% ~J% K% PRINT I% J% K% ~I% ~J% ~K% =K% ENDPROC -- Alan Adams, from Northamptonshire alan@adamshome.org.uk http://www.nckc.org.uk/
[toc] | [next] | [standalone]
| From | Martin <News03@avisoft.f9.co.uk> |
|---|---|
| Date | 2020-01-03 19:31 +0000 |
| Message-ID | <582cb030b8News03@avisoft.f9.co.uk> |
| In reply to | #5921 |
On 03 Jan in article <4adaa32c58.Alan.Adams@ArmX6.adamshome.org.uk>,
Alan Adams <alan@adamshome.org.uk> wrote:
> I've either discovered something odd but useful about BASIC, or
> I#ve got myself rather confused.
> The issue arose because I need to subtract one 5-byte time from
> another, returning the result in an integer.
> This will obviously fail if the result is too large to fit in an
> integer, but that is a large number of days, and will not occur in
> my particular case, as the computers will not need to run that
> long without a restart.
> What I thinki I've discovered is that although BASIC treats values
> that go beyone &7fffffff as negative numbers, when suntracting
> them one from another it treats them as unsigned. The following
> example demonstrates why I think this is the case.
> Note that I'm ignoring the MSB of the 5-byte times, as the test was
> created to fnd out what I needed to do with it, and seems to show
> that I simply ignore it.
> The weird example is the third, where subtracting a very large
> positive number from a very large negative number produces a
> positive result.
> Comments please:
I think you are confused. BASIC integers are *always* 4 bytes, never
5 bytes. The statement
I%=!buf1%
sets I% to the first 4 bytes at address buf1%
Which I think will explain your results.
There is no way for BASIC to subtract two 5-byte integers, apart from
spliiting each to one 5-byte integer and one 1-bute - and handling
the case where the result is negative.
However, if the difference is small, or you can ignore the lest
significant byte, you may be able to chose a single 4-bytes that will
provide the difference.
--
Martin Avison
Note that unfortunately this email address will become invalid
without notice if (when) any spam is received.
[toc] | [prev] | [next] | [standalone]
| From | druck <news@druck.org.uk> |
|---|---|
| Date | 2020-01-03 21:00 +0000 |
| Message-ID | <quoa19$o6o$1@dont-email.me> |
| In reply to | #5922 |
On 03/01/2020 19:31, Martin wrote: > There is no way for BASIC to subtract two 5-byte integers, apart from > spliiting each to one 5-byte integer and one 1-bute - and handling > the case where the result is negative. I'd always opt for a bit of assembler to do that, as its every easy to do arbitrary sized arithmetic when you've got access to the CPU flags. > However, if the difference is small, or you can ignore the lest > significant byte, you may be able to chose a single 4-bytes that will > provide the difference. I'd never recommend that, no matter how sort the interval, an over flow will occur at some point (the next in about 10 years from now). But anyway this highlights the lack of date and time manipulation SWIs in RISC OS. The only things you can do with a 5 byte time is convert it to or from a string. ---druck
[toc] | [prev] | [next] | [standalone]
| From | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| Date | 2020-01-03 22:26 +0000 |
| Message-ID | <ef3ac02c58.Alan.Adams@ArmX6.adamshome.org.uk> |
| In reply to | #5923 |
In message <quoa19$o6o$1@dont-email.me>
druck <news@druck.org.uk> wrote:
> On 03/01/2020 19:31, Martin wrote:
>> There is no way for BASIC to subtract two 5-byte integers, apart from
>> spliiting each to one 5-byte integer and one 1-bute - and handling
>> the case where the result is negative.
> I'd always opt for a bit of assembler to do that, as its every easy to
> do arbitrary sized arithmetic when you've got access to the CPU flags.
>> However, if the difference is small, or you can ignore the lest
>> significant byte, you may be able to chose a single 4-bytes that will
>> provide the difference.
> I'd never recommend that, no matter how sort the interval, an over flow
> will occur at some point (the next in about 10 years from now).
> But anyway this highlights the lack of date and time manipulation SWIs
> in RISC OS. The only things you can do with a 5 byte time is convert it
> to or from a string.
> ---druck
I was starting to think of using assembler.
The difference between the times will never be more than a day. However
the times are the time stored in the computer, which is close to the
actual date and time. So it's not impossible that at some point each of
the edge cases in the example might occur, i/e.
low word goes from 7f ff ff ff to 80 00 00 00
Low word goes from ff ff ff ff to 00 00 00 00 and the high byte is
incremented.
(I'm going to ignore the case when time goes from ff ff ff ff ff to 00 00
00 00 00.)
The example was written so that I could get my head round what happened
when I subtracted 7f ff ff f0 from 80 00 00 0f for example. What I really
didn't expect was a positive, and correct, answer, since PRINTing the
variables said I was subtracting a large positive number from a large
negative one. I expected a negative underflow, not a valid positive
result.
(My suspicion is that the calculation is done ignoring the underflow, and
the result returned is the remainder.)
If I could assume that this behaviour of BASIC would continue unchanged,
then I could make use of it. Since it seems to me to be incorrect
(although useful) I really ought to avoid using it, in case it gets
corrected, and the only way I know to do that is assembler.
--
Alan Adams, from Northamptonshire
alan@adamshome.org.uk
http://www.nckc.org.uk/
[toc] | [prev] | [next] | [standalone]
| From | Steve Drain <steve@kappa.me.uk> |
|---|---|
| Date | 2020-01-04 10:40 +0000 |
| Message-ID | <qupq4i$4nf$1@gioia.aioe.org> |
| In reply to | #5924 |
druck wrote: > I'd always opt for a bit of assembler to do that, as its every easy > to do arbitrary sized arithmetic when you've got access to the CPU > flags. +1 > But anyway this highlights the lack of date and time manipulation > SWIs in RISC OS. The only things you can do with a 5 byte time is > convert it to or from a string. I approached this lack ages ago in Basalt, which has a comprehensive set of datetime keywords. 5-byte datetime values are held in float variables, but the float value is meaningless except when used with appropriate keywords. So, you could do: interval%=SECONDS(datetime2 - datetime1) ;-) Maybe I could develop a module from this.
[toc] | [prev] | [next] | [standalone]
| From | Martin <News03@avisoft.f9.co.uk> |
|---|---|
| Date | 2020-01-04 16:08 +0000 |
| Message-ID | <582d216fd8News03@avisoft.f9.co.uk> |
| In reply to | #5925 |
On 04 Jan in article <qupq4i$4nf$1@gioia.aioe.org>,
Steve Drain <steve@kappa.me.uk> wrote:
> druck wrote:
> > I'd always opt for a bit of assembler to do that, as its every
> > easy to do arbitrary sized arithmetic when you've got access to
> > the CPU flags.
> +1
> > But anyway this highlights the lack of date and time manipulation
> > SWIs in RISC OS. The only things you can do with a 5 byte time is
> > convert it to or from a string.
> I approached this lack ages ago in Basalt, which has a
> comprehensive set of datetime keywords. 5-byte datetime values are
> held in float variables, but the float value is meaningless except
> when used with appropriate keywords.
> So, you could do:
> interval%=SECONDS(datetime2 - datetime1)
> ;-)
> Maybe I could develop a module from this.
I have thought about this again, and re-read Alan's original post
more carefully. I would agree with druck's suggestion (although I did
not see his full post) that using assembler to subtract the full 5
bytes correctly is undoubtedly the best way to ensure that all
possible values are catered for correctly.
However, two points should be considered from Alan's post.
1. The answer is a relatively small positive time difference.
If 1 day maximum, this is only 8,640,000 or &83D600.
The MSB 5th byte only changes about every 500 days.
2. Alan said
> The weird example is the third, where subtracting a very large
> positive number from a very large negative number produces a
> positive result.
But this result is not weird, it is correct - because as they are
both UNSIGNED it is subtracting a very large number from an even
larger number. The result is a small number, which is correct.
The strange thing about 2's complement arithmetic is that it works
for both signed and unsigned numbers. The first 4 bytes of a 5-byte
time block are unsigned, so cannot be regarded as negative. It even
works when the MSB 5th byte has changed, as the last example shows.
So, I would suggest that using
I% = !buf1%
J% = !buf2%
K% = I%-J%
will suffice to calculate a time difference of a few days in cs.
... unless anyone can see the flaws in my argument!
--
Martin Avison
Note that unfortunately this email address will become invalid
without notice if (when) any spam is received.
[toc] | [prev] | [next] | [standalone]
| From | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| Date | 2020-01-04 16:22 +0000 |
| Message-ID | <a2bf222d58.Alan.Adams@ArmX6.adamshome.org.uk> |
| In reply to | #5926 |
In message <582d216fd8News03@avisoft.f9.co.uk>
Martin <News03@avisoft.f9.co.uk> wrote:
> On 04 Jan in article <qupq4i$4nf$1@gioia.aioe.org>,
> Steve Drain <steve@kappa.me.uk> wrote:
>> druck wrote:
<snip>
> 2. Alan said
>> The weird example is the third, where subtracting a very large
>> positive number from a very large negative number produces a
>> positive result.
> But this result is not weird, it is correct - because as they are
> both UNSIGNED it is subtracting a very large number from an even
> larger number. The result is a small number, which is correct.
> The strange thing about 2's complement arithmetic is that it works
> for both signed and unsigned numbers. The first 4 bytes of a 5-byte
> time block are unsigned, so cannot be regarded as negative. It even
> works when the MSB 5th byte has changed, as the last example shows.
> So, I would suggest that using
> I% = !buf1%
> J% = !buf2%
> K% = I%-J%
> will suffice to calculate a time difference of a few days in cs.
That agrees with what I found. It even seems to work in a case where the
5th (highest) byte is incremented.
The thing I found surprising is that BASIC displays the values in I% and
J% using a signed interpretation, but does the subtraction in an unsigned
fashion. It's this inconsistency that worries me, in case at some future
date is is "corrected".
> ... unless anyone can see the flaws in my argument!
--
Alan Adams, from Northamptonshire
alan@adamshome.org.uk
http://www.nckc.org.uk/
[toc] | [prev] | [next] | [standalone]
| From | David Higton <dave@davehigton.me.uk> |
|---|---|
| Date | 2020-01-04 17:24 +0000 |
| Message-ID | <d46b282d58.DaveMeUK@BeagleBoard-xM> |
| In reply to | #5927 |
In message <a2bf222d58.Alan.Adams@ArmX6.adamshome.org.uk>
Alan Adams <alan@adamshome.org.uk> wrote:
>The thing I found surprising is that BASIC displays the values in I% and
>J% using a signed interpretation, but does the subtraction in an unsigned
>fashion. It's this inconsistency that worries me, in case at some future
>date is is "corrected".
It's not inconsistent. This is just how 2's complement addition and
subtraction work. Perhaps you need to work through some more examples.
Doing them on paper, perhaps with a more limited number of bits to make
it less laborious, might help convince you.
David
[toc] | [prev] | [next] | [standalone]
| From | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| Date | 2020-01-04 18:47 +0000 |
| Message-ID | <930f302d58.Alan.Adams@ArmX6.adamshome.org.uk> |
| In reply to | #5928 |
In message <d46b282d58.DaveMeUK@BeagleBoard-xM>
David Higton <dave@davehigton.me.uk> wrote:
> In message <a2bf222d58.Alan.Adams@ArmX6.adamshome.org.uk>
> Alan Adams <alan@adamshome.org.uk> wrote:
>>The thing I found surprising is that BASIC displays the values in I% and
>>J% using a signed interpretation, but does the subtraction in an unsigned
>>fashion. It's this inconsistency that worries me, in case at some future
>>date is is "corrected".
> It's not inconsistent. This is just how 2's complement addition and
> subtraction work. Perhaps you need to work through some more examples.
> Doing them on paper, perhaps with a more limited number of bits to make
> it less laborious, might help convince you.
Ity may not be inconsistent if you view it from the viewpoint of
assembler, but it is very much inconsistent from the viewpoint of BASIC
-(very large number) - (another very large number) should never result in
a positive answer.
BASIC shows these values as negative, and returns positive.
That's inconsistent "within the BASIC language scope". It should, to be
consistent, return an underflow error.
Where it is consistent is that it does the same thing with addition, but
not with multiplication.
>a%=&7ffffff0
>b%=&7fffff00
>PRINT a%
2.14748363E9
>PRINT b%
2.14748339E9
>PRINT a%+b%
-272
>PRINT a%*2
4.29496726E9
>PRINT b%*2
4.29496678E9
>
>PRINT ~(a%*2)
Number too big
--
Alan Adams, from Northamptonshire
alan@adamshome.org.uk
http://www.nckc.org.uk/
[toc] | [prev] | [next] | [standalone]
| From | Matthew Phillips <spam2011m@yahoo.co.uk> |
|---|---|
| Date | 2020-01-06 08:58 +0000 |
| Message-ID | <7ad0012e58.Matthew@sinenomine.freeserve.co.uk> |
| In reply to | #5929 |
In message <930f302d58.Alan.Adams@ArmX6.adamshome.org.uk> on 4 Jan 2020 Alan Adams wrote: > In message <d46b282d58.DaveMeUK@BeagleBoard-xM> > David Higton <dave@davehigton.me.uk> wrote: > > > In message <a2bf222d58.Alan.Adams@ArmX6.adamshome.org.uk> > > Alan Adams <alan@adamshome.org.uk> wrote: > > >>The thing I found surprising is that BASIC displays the values in I% and > >>J% using a signed interpretation, but does the subtraction in an unsigned > >>fashion. It's this inconsistency that worries me, in case at some future > >>date is is "corrected". > > > It's not inconsistent. This is just how 2's complement addition and > > subtraction work. Perhaps you need to work through some more examples. > > Doing them on paper, perhaps with a more limited number of bits to make > > it less laborious, might help convince you. > > Ity may not be inconsistent if you view it from the viewpoint of > assembler, but it is very much inconsistent from the viewpoint of BASIC > > -(very large number) - (another very large number) should never result in > a positive answer. > > BASIC shows these values as negative, and returns positive. > > That's inconsistent "within the BASIC language scope". It should, to be > consistent, return an underflow error. I agree with you, Alan. BBC BASIC is behaving more like a low level language than I would have expected. It happens to be useful for the some purposes, but not as useful as it could be - as druck says it's easier to do 5-byte arithmetic in assembly language because you have access to the flags. Some implementations of BASIC behave differently. Locomotive BASIC on the Amstrad CPC has integer types limited to 16 bits, as it happens. This is how it behaves: a%=-32768 PRINT a%-&7000 -61440 b%=a%-&7000 Overflow So you see that the arithmetic is being done correctly, possibly by converting to floating point which might have more bits of precision available, but if you try to assign the result to an integer variable, it knows that it's not going to fit. Your example code was performing the subtraction, placing the result in K% and then reporting the value of K%. So what your test does not make clear is whether BASIC has worked out the correct value of the result, and then truncated it to fit into the 32-bit variable, or whether it has already wrapped round in its calculations. Here's a test at the BASIC prompt: >a%=-127*256*256*256 >P.a% -2.13070643E9 >P.~a% 81000000 >P.a%-&7FFFFFF 2.03004314E9 >P.~(a%-&7FFFFFF) 79000001 So BASIC has produced a large positive result. It appears that it has spotted that a% and &7FFFFFF can both be represented as signed 32-bit integers, and has performed the calculation using 32 bits for the result as well. By contrast if we use a floating point variable... >a=-127*256*256*256 >P.a-&7FFFFFF -2.26492416E9 More modern scripting languages like Perl will dynamically change the types of variables to fit what is being put into them, rather than sticking with the most compact type and ending up with what appear to be wrong answers. > Where it is consistent is that it does the same thing with addition, but > not with multiplication. > > >a%=&7ffffff0 > >b%=&7fffff00 > >PRINT a% > 2.14748363E9 > >PRINT b% > 2.14748339E9 > >PRINT a%+b% > -272 > >PRINT a%*2 > 4.29496726E9 > >PRINT b%*2 > 4.29496678E9 > > > >PRINT ~(a%*2) > Number too big I suppose the problem is much more conspicuous with multiplication, and so the designers of BBC BASIC made more effort to do the right thing. I'd be interested to see how BBC BASIC behaves on an 8-bit machine like the BBC B. -- Matthew Phillips Durham
[toc] | [prev] | [next] | [standalone]
| From | David Higton <dave@davehigton.me.uk> |
|---|---|
| Date | 2020-01-06 16:20 +0000 |
| Message-ID | <60432a2e58.DaveMeUK@BeagleBoard-xM> |
| In reply to | #5929 |
In message <930f302d58.Alan.Adams@ArmX6.adamshome.org.uk>
Alan Adams <alan@adamshome.org.uk> wrote:
>In message <d46b282d58.DaveMeUK@BeagleBoard-xM>
> David Higton <dave@davehigton.me.uk> wrote:
>
>> In message <a2bf222d58.Alan.Adams@ArmX6.adamshome.org.uk>
>> Alan Adams <alan@adamshome.org.uk> wrote:
>
>>>The thing I found surprising is that BASIC displays the values in I% and
>>>J% using a signed interpretation, but does the subtraction in an unsigned
>>>fashion. It's this inconsistency that worries me, in case at some future
>>>date is is "corrected".
>
>> It's not inconsistent. This is just how 2's complement addition and
>> subtraction work. Perhaps you need to work through some more examples.
>> Doing them on paper, perhaps with a more limited number of bits to make
>> it less laborious, might help convince you.
>
>It may not be inconsistent if you view it from the viewpoint of
>assembler, but it is very much inconsistent from the viewpoint of BASIC
>
>-(very large number) - (another very large number) should never result in
>a positive answer.
>
>BASIC shows these values as negative, and returns positive.
>
>That's inconsistent "within the BASIC language scope". It should, to be
>consistent, return an underflow error.
You're making an assumption that, in BASIC, integers can only be signed,
and that's what everyone wants. Now I know that BASIC represents them
in PRINT statements as signed, but I don't regard that as the end of the
story. I am well used to thinking about whether I want each one of my
integers to be signed or unsigned. I'm quite happy to use BASIC to
handle unsigned integers. The important thing is that it doesn't fall
over with an error; I'm quite happy to interpret the result of the
calculation myself. (I'm also happy to add a signed integer to an
unsigned integer, etc.)
To my mind and my needs, BASIC does the right thing.
>Where it is consistent is that it does the same thing with addition, but
>not with multiplication.
That's the same in machine language, AFAIUI. Addition and subtraction
instructions don't need to have signed and unsigned variants, but
multiplication (despite being repeated addition) /does/ require them.
I don't understand why, bearing in mind my comment in brackets, and if
anyone can point me to an explanation, I'd be grateful.
David
[toc] | [prev] | [next] | [standalone]
| From | Matthew Phillips <spam2011m@yahoo.co.uk> |
|---|---|
| Date | 2020-01-07 08:49 +0000 |
| Message-ID | <4ad6842e58.Matthew@sinenomine.freeserve.co.uk> |
| In reply to | #5932 |
In message <60432a2e58.DaveMeUK@BeagleBoard-xM> on 6 Jan 2020 David Higton wrote: > In message <930f302d58.Alan.Adams@ArmX6.adamshome.org.uk> > Alan Adams <alan@adamshome.org.uk> wrote: > > >In message <d46b282d58.DaveMeUK@BeagleBoard-xM> > > David Higton <dave@davehigton.me.uk> wrote: > > > >> In message <a2bf222d58.Alan.Adams@ArmX6.adamshome.org.uk> > >> Alan Adams <alan@adamshome.org.uk> wrote: > > > >>>The thing I found surprising is that BASIC displays the values in I% and > >>>J% using a signed interpretation, but does the subtraction in an unsigned > >>>fashion. It's this inconsistency that worries me, in case at some future > >>>date is is "corrected". > > > >> It's not inconsistent. This is just how 2's complement addition and > >> subtraction work. Perhaps you need to work through some more examples. > >> Doing them on paper, perhaps with a more limited number of bits to make > >> it less laborious, might help convince you. > > > >It may not be inconsistent if you view it from the viewpoint of > >assembler, but it is very much inconsistent from the viewpoint of BASIC > > > >-(very large number) - (another very large number) should never result in > >a positive answer. > > > >BASIC shows these values as negative, and returns positive. > > > >That's inconsistent "within the BASIC language scope". It should, to be > >consistent, return an underflow error. > > You're making an assumption that, in BASIC, integers can only be signed, > and that's what everyone wants. Now I know that BASIC represents them > in PRINT statements as signed, but I don't regard that as the end of the > story. I am well used to thinking about whether I want each one of my > integers to be signed or unsigned. I'm quite happy to use BASIC to > handle unsigned integers. The important thing is that it doesn't fall > over with an error; I'm quite happy to interpret the result of the > calculation myself. (I'm also happy to add a signed integer to an > unsigned integer, etc.) > > To my mind and my needs, BASIC does the right thing. > > >Where it is consistent is that it does the same thing with addition, but > >not with multiplication. > > That's the same in machine language, AFAIUI. Addition and subtraction > instructions don't need to have signed and unsigned variants, but > multiplication (despite being repeated addition) /does/ require them. > I don't understand why, bearing in mind my comment in brackets, and if > anyone can point me to an explanation, I'd be grateful. You'll note that in ARM assembly language MUL does not have signed/unsigned variants. It takes two 32-bit registers, multiplies them, and puts the result in a 32-bit register, discarding any overflow. That works just as well for signed and unsigned numbers. The reason the long multiplication instructions, SMULL and UMULL, have signed and unsigned versions is that the result has 64 bits despite the operands each being 32 bits. In two's complement representation, if you have a negative number like -1 (11111111,11111111,11111111,11111111) then if you want to put the result in 64-bit form you need to extend it to fill the top 32 bits with 1 as well. Taking things down to a more manageable size, 8 bits and 16 bits: In 8 bits, 11111111 is -1 (or 255 if unsigned) 11111111 * 2 is 11111110 That's an overflow if the number was unsigned, but it's -2 if signed. But if you put the result in a 16 bit register, you will get 00000001 11111110 which is 510, and not -2, unless you have told the processor that you are doing signed arithmetic, in which case it can make sure that the extra bits are filled with the appropriate number depending on the sign of the result. You said about that you're quite happy to interpret the result of the calculation yourself and that the important thing is that it doesn't fall over with an error. That's all very well, but there are many applications where it is better to know about overflows than to ignore them. If you wrote an accounts package, you might decide to store all the values as integers, in pennies, to avoid floating point rounding errors. That's fine if you don't need to deal with any values bigger than £21,474,836.47. But if a business with a big turnover buys your accounting package, they will get very cross if you have not guarded against overflow. It would be an utter pain for anyone writing stuff in BASIC to have to check each calculation to decide whether an overflow had occurred or not. If BASIC generated a "Number too big" error for addition and subtraction of integers, if you want to ignore them, all you need to do is to write a suitable error handler. The analogy with assembly language is not all that helpful, because you have access to the flags which make it easy to check whether a calculation has resulted in an overflow. BASIC's behaviour encourages people to be careless. Locomotive BASIC on the Amstrad CPC generates on overflow error if you exceed the 16 bits for integer calculations. This is absolutely necessary because 32768 is not a very bit number for an upper limit. I think Acorn only got away with it because 32 bits gives pretty big numbers which are adequate for most purposes. -- Matthew Phillips Durham
[toc] | [prev] | [next] | [standalone]
| From | Martin <News03@avisoft.f9.co.uk> |
|---|---|
| Date | 2020-01-07 11:20 +0000 |
| Message-ID | <582e9297f8News03@avisoft.f9.co.uk> |
| In reply to | #5937 |
On 07 Jan in article <4ad6842e58.Matthew@sinenomine.freeserve.co.uk>, Matthew Phillips <spam2011m@yahoo.co.uk> wrote: > It would be an utter pain for anyone writing stuff in BASIC to have > to check each calculation to decide whether an overflow had > occurred or not. If BASIC generated a "Number too big" error for > addition and subtraction of integers, if you want to ignore them, > all you need to do is to write a suitable error handler. Sorry, but I have to disagree! Because a BASIC integer can be either signed or unsigned (and BASIC does not know which) I do not think it is possible for BASIC to generate any under/overflow errors for addition or subtraction. Consider the following four examples - two for addition and two for subtraction. Each example has the same numbers on the left shown as signed, and on the right as unsigned hex. You will see that each example has an obvious error case - BUT only when used as either Signed or Unsigned, never both. Signed Addition Unsigned addition --------------- ----------------- 2147483632 + 200 = -2147483464 &7FFFFFF0 + &C8 = &800000B8 Overflow set = Overflow Carry clear = OK -16 + 200 = 184 &FFFFFFF0 + &C8 = &B8 Overflow clear = OK Carry set = Overflow Signed Subtraction Unsigned Subtraction ------------------ -------------------- 100 - 200 = -100 &64 - &C8 = &FFFFFF9C Overflow clear = OK Carry clear = Underflow -2147483516 - 2147483392 = 388 &80000084 - &7FFFFF00 = &184 Overflow set = Underflow Carry set = OK The last example above is the same case as the third 'weird' example from Alan's original post. It may look like an error if signed, but perfectly logical if unsigned. So, I think that it has to be the application which does any necessary checks, as long as BASIC cannot tell whether an integer is signed or unsigned. ... unless anyone can see the flaws in my argument! Martin -- Martin Avison Note that unfortunately this email address will become invalid without notice if (when) any spam is received.
[toc] | [prev] | [next] | [standalone]
| From | David Higton <dave@davehigton.me.uk> |
|---|---|
| Date | 2020-01-07 15:05 +0000 |
| Message-ID | <893aa72e58.DaveMeUK@BeagleBoard-xM> |
| In reply to | #5938 |
In message <582e9297f8News03@avisoft.f9.co.uk>
Martin <News03@avisoft.f9.co.uk> wrote:
> On 07 Jan in article <4ad6842e58.Matthew@sinenomine.freeserve.co.uk>,
> Matthew Phillips <spam2011m@yahoo.co.uk> wrote:
> > It would be an utter pain for anyone writing stuff in BASIC to have to
> > check each calculation to decide whether an overflow had occurred or not.
> > If BASIC generated a "Number too big" error for addition and subtraction
> > of integers, if you want to ignore them, all you need to do is to write a
> > suitable error handler.
>
> Sorry, but I have to disagree!
>
> Because a BASIC integer can be either signed or unsigned (and BASIC does
> not know which) I do not think it is possible for BASIC to generate any
> under/overflow errors for addition or subtraction.
>
> Consider the following four examples - two for addition and two for
> subtraction. Each example has the same numbers on the left shown as signed,
> and on the right as unsigned hex.
>
> You will see that each example has an obvious error case - BUT only when
> used as either Signed or Unsigned, never both.
>
>Signed Addition Unsigned addition
>--------------- -----------------
>2147483632 + 200 = -2147483464 &7FFFFFF0 + &C8 = &800000B8
>Overflow set = Overflow Carry clear = OK
>
>-16 + 200 = 184 &FFFFFFF0 + &C8 = &B8
>Overflow clear = OK Carry set = Overflow
>
>
>Signed Subtraction Unsigned Subtraction
>------------------ --------------------
>100 - 200 = -100 &64 - &C8 = &FFFFFF9C
>Overflow clear = OK Carry clear = Underflow
>
>-2147483516 - 2147483392 = 388 &80000084 - &7FFFFF00 = &184
>Overflow set = Underflow Carry set = OK
>
> The last example above is the same case as the third 'weird' example from
> Alan's original post. It may look like an error if signed, but perfectly
> logical if unsigned.
>
> So, I think that it has to be the application which does any necessary
> checks, as long as BASIC cannot tell whether an integer is signed or
> unsigned.
>
> ... unless anyone can see the flaws in my argument!
I'm in agreement with you, Martin. BASIC cannot know whether integer
variables are being used as signed or unsigned. It would be a real
pain if it decided that an error had occurred when really it hadn't;
the results of the calculation could never be seen. It would mean
descending into assembly language - which we /really/ don't want to
do.
I would point out that it is also legitimate to add a signed int to
an unsigned one, e.g. to add an offset in either direction to a pointer.
You can see that adding a negative offset to a top-bit-set address
would appear to overflow, when in reality no error occurs.
David
[toc] | [prev] | [next] | [standalone]
| From | Matthew Phillips <spam2011m@yahoo.co.uk> |
|---|---|
| Date | 2020-01-08 08:23 +0000 |
| Message-ID | <bc36062f58.Matthew@sinenomine.freeserve.co.uk> |
| In reply to | #5939 |
In message <893aa72e58.DaveMeUK@BeagleBoard-xM>
on 7 Jan 2020 David Higton wrote:
> In message <582e9297f8News03@avisoft.f9.co.uk>
> Martin <News03@avisoft.f9.co.uk> wrote:
>
> > On 07 Jan in article <4ad6842e58.Matthew@sinenomine.freeserve.co.uk>,
> > Matthew Phillips <spam2011m@yahoo.co.uk> wrote:
> > > It would be an utter pain for anyone writing stuff in BASIC to have to
> > > check each calculation to decide whether an overflow had occurred or
> > > not. If BASIC generated a "Number too big" error for addition and
> > > subtraction of integers, if you want to ignore them, all you need to do
> > > is to write a suitable error handler.
> >
> > Sorry, but I have to disagree!
> >
> > Because a BASIC integer can be either signed or unsigned (and BASIC does
> > not know which) I do not think it is possible for BASIC to generate any
> > under/overflow errors for addition or subtraction.
> >
> > Consider the following four examples - two for addition and two for
> > subtraction. Each example has the same numbers on the left shown as signed,
> > and on the right as unsigned hex.
> >
> > You will see that each example has an obvious error case - BUT only when
> > used as either Signed or Unsigned, never both.
> >
> >Signed Addition Unsigned addition
> >--------------- -----------------
> >2147483632 + 200 = -2147483464 &7FFFFFF0 + &C8 = &800000B8
> >Overflow set = Overflow Carry clear = OK
> >
> >-16 + 200 = 184 &FFFFFFF0 + &C8 = &B8
> >Overflow clear = OK Carry set = Overflow
> >
> >
> >Signed Subtraction Unsigned Subtraction
> >------------------ --------------------
> >100 - 200 = -100 &64 - &C8 = &FFFFFF9C
> >Overflow clear = OK Carry clear = Underflow
> >
> >-2147483516 - 2147483392 = 388 &80000084 - &7FFFFF00 = &184
> >Overflow set = Underflow Carry set = OK
> >
> > The last example above is the same case as the third 'weird' example from
> > Alan's original post. It may look like an error if signed, but perfectly
> > logical if unsigned.
> >
> > So, I think that it has to be the application which does any necessary
> > checks, as long as BASIC cannot tell whether an integer is signed or
> > unsigned.
My position is that BASIC sitting on the fence like this is ultimately not
much help to programmers who have a definite idea whether the values they are
dealing with are signed or unsigned, because in each case there are
circumstances in which you will not be told about overflows or carries. If
you're happy to be vague about whether the value is signed or unsigned, BASIC
might suit you.
Remember that although you have written "Carry set" and "Overflow set", BASIC
doesn't provide the programmer with access to this information (unless I'm
missing something).
> I'm in agreement with you, Martin. BASIC cannot know whether integer
> variables are being used as signed or unsigned. It would be a real pain if
> it decided that an error had occurred when really it hadn't; the results of
> the calculation could never be seen. It would mean descending into
> assembly language - which we /really/ don't want to do.
>
> I would point out that it is also legitimate to add a signed int to
> an unsigned one, e.g. to add an offset in either direction to a pointer.
> You can see that adding a negative offset to a top-bit-set address
> would appear to overflow, when in reality no error occurs.
I agree that BASIC's behaviour is really useful when dealing with passing
flags to SWIs and handling memory addresses. But there are also many
situations in which not having an error generated is a nuisance. If you have
the address &ffff fffc and want to add -12 to get &ffff fff0 that's fine, but
what if you add 12? You'd want to know that you've wrapped round to zero
page.
I hope you can both agree that BASIC is inconsistent between add/sub and
multiplication. With addition and subtraction BASIC gives no errors if the
individual operands can all be expressed within 32 bits, whether the values
are signed or unsigned. But with multiplication, the values are firmly
treated as signed:
>a%=&7fffffff
>b%=a%*2
Number too big
>a%=&3fffffff
>b%=a%*2
>P. b%
2.14748365E9
Negative numbers:
>a%=&C0000000
>P. a%
-1.07374182E9
>b%=a%*2
>P. b%
-2.14748365E9
>P. ~b%
80000000
>c%=b%*2
Number too big
I know Dave argued that multiplication is different for signed and unsigned
integers in assembly language, but that's only the case if you're storing a
64 bit result from two 32 bit numbers.
There is further weirdness. Consider this, where the values are assigned to
floating point variables:
>a=&7fffffff
a=a+a
P.a
4.29496729E9
>a=&7fffffff+&7fffffff
>P.a
-2
Or in decimal notation:
>a=2100000000+2100000000
>P. a
-94967296
>
>a=2100000000
>a=a+a
>P.a
4.2E9
>a=2200000000+2200000000
>P.a
4.4E9
In short, while I can understand what BASIC is doing, and can see that it is
useful in some special circumstances (dealing with flags and addresses) its
behaviour is unexpected if you are not au fait with assembly language and it
is full of traps for the unwary.
If BASIC gave you access to the overflow and carry indicators or allowed you
to declare variables as signed or unsigned it would be better. However, we
have to live with it as it is: I'm certainly not advocating changing it.
It's possible to avoid the 2100000000+2100000000 trap in a similar way to C
by writing 2100000000.0+2100000000.0
I only really got into Acorn machines with the Archimedes. Were integers on
the BBC B also 32 bit?
--
Matthew Phillips
Durham
[toc] | [prev] | [next] | [standalone]
| From | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| Date | 2020-01-08 10:26 +0000 |
| Message-ID | <768b112f58.Alan.Adams@ArmX6.adamshome.org.uk> |
| In reply to | #5940 |
In message <bc36062f58.Matthew@sinenomine.freeserve.co.uk>
Matthew Phillips <spam2011m@yahoo.co.uk> wrote:
> In message <893aa72e58.DaveMeUK@BeagleBoard-xM>
> on 7 Jan 2020 David Higton wrote:
>> In message <582e9297f8News03@avisoft.f9.co.uk>
>> Martin <News03@avisoft.f9.co.uk> wrote:
>>
>>> On 07 Jan in article <4ad6842e58.Matthew@sinenomine.freeserve.co.uk>,
<huge snip>
> I only really got into Acorn machines with the Archimedes. Were integers on
> the BBC B also 32 bit?
I'm fairly sure that BBC micro BASIC integers were 16-bit. The highest
number was 32767, the lowest -32767
--
Alan Adams, from Northamptonshire
alan@adamshome.org.uk
http://www.nckc.org.uk/
[toc] | [prev] | [next] | [standalone]
| From | druck <news@druck.org.uk> |
|---|---|
| Date | 2020-01-08 21:02 +0000 |
| Message-ID | <qv5g17$eaj$1@dont-email.me> |
| In reply to | #5941 |
On 08/01/2020 10:26, Alan Adams wrote: >>> In message <582e9297f8News03@avisoft.f9.co.uk> >>> Martin <News03@avisoft.f9.co.uk> wrote: >>> >>>> On 07 Jan in article <4ad6842e58.Matthew@sinenomine.freeserve.co.uk>, > <huge snip> > > >> I only really got into Acorn machines with the Archimedes. Were integers on >> the BBC B also 32 bit? > > I'm fairly sure that BBC micro BASIC integers were 16-bit. The highest > number was 32767, the lowest -32767 No, Acorn never did anything in 16 bits, BBC Basic has always had 32 bit integers. Have a play on JS Beeb https://bbc.godbolt.org/ ---druck
[toc] | [prev] | [next] | [standalone]
| From | Richard Ashbery <basura@invalid.addr.uk> |
|---|---|
| Date | 2020-01-09 12:53 +0000 |
| Message-ID | <582fa2d266basura@invalid.addr.uk> |
| In reply to | #5943 |
In article <qv5g17$eaj$1@dont-email.me>, druck <news@druck.org.uk> wrote: > No, Acorn never did anything in 16 bits, BBC Basic has always had > 32 bit integers. Have a play on JS Beeb https://bbc.godbolt.org/ What a great bit of nostalgia! Excellent research in finding it. Ironic that you can't run the simulator in NetSurf! Richard
[toc] | [prev] | [next] | [standalone]
| From | Steve Fryatt <news@stevefryatt.org.uk> |
|---|---|
| Date | 2020-01-09 23:16 +0000 |
| Message-ID | <mpro.q3v4nt01j5qyf01nd.news@stevefryatt.org.uk> |
| In reply to | #5947 |
On 9 Jan, Richard Ashbery wrote in message
<582fa2d266basura@invalid.addr.uk>:
> In article <qv5g17$eaj$1@dont-email.me>, druck <news@druck.org.uk> wrote:
>
> > No, Acorn never did anything in 16 bits, BBC Basic has always had 32 bit
> > integers. Have a play on JS Beeb https://bbc.godbolt.org/
>
> What a great bit of nostalgia! Excellent research in finding it.
It's been around a while: I found it back in 2018 whilst looking at the
archive of the BBC Computer Literacy Project, when I spotted Matt Godbolt's
name and then discovered that he mentioned one Richard Talbot-Watkins in the
emulator's credits... Two names that readers of AU's *Info back in the 1990s
should recognise.
There was a short article in the Wakefield newsletter about it at the time
-- the CLP Archive site is worth a visit for more nostalgia, IIRC. A little
worryingly, it turns out to have been September 2018... time flies.
--
Steve Fryatt - Leeds, England
http://www.stevefryatt.org.uk/
[toc] | [prev] | [next] | [standalone]
| From | Steve Fryatt <news@stevefryatt.org.uk> |
|---|---|
| Date | 2020-01-08 22:35 +0000 |
| Message-ID | <mpro.q3t8280166x2301iz.news@stevefryatt.org.uk> |
| In reply to | #5941 |
On 8 Jan, Alan Adams wrote in message
<768b112f58.Alan.Adams@ArmX6.adamshome.org.uk>:
> In message <bc36062f58.Matthew@sinenomine.freeserve.co.uk>
> Matthew Phillips <spam2011m@yahoo.co.uk> wrote:
>
> > I only really got into Acorn machines with the Archimedes. Were
> > integers on the BBC B also 32 bit?
>
> I'm fairly sure that BBC micro BASIC integers were 16-bit. The highest
> number was 32767, the lowest -32767
I'm pretty sure they weren't. On the Beeb and its 8-bit bretheren, BASIC
used 4 byte integers and 5 byte floats, just like now.
The Atom was a different BASIC, but the internet seems to think it also had
32-bit integers.
--
Steve Fryatt - Leeds, England
http://www.stevefryatt.org.uk/
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.sys.acorn.programmer
csiph-web