Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.sys.acorn.programmer > #5981 > unrolled thread
| Started by | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| First post | 2020-02-18 11:55 +0000 |
| Last post | 2020-02-20 11:18 +0000 |
| Articles | 12 on this page of 32 — 10 participants |
Back to article view | Back to comp.sys.acorn.programmer
Subtracting times Alan Adams <alan@adamshome.org.uk> - 2020-02-18 11:55 +0000
Re: Subtracting times Jean-Michel <jmc.bruck@orange.fr> - 2020-02-18 19:11 +0100
Re: Subtracting times Steve Drain <steve@kappa.me.uk> - 2020-02-21 03:28 -0800
Re: Subtracting times Alan Adams <alan@adamshome.org.uk> - 2020-02-21 12:45 +0000
Re: Subtracting times Alan Adams <alan@adamshome.org.uk> - 2020-02-21 15:17 +0000
Re: Subtracting times Steve Drain <steve@kappa.me.uk> - 2020-02-22 10:37 +0000
Re: Subtracting times Steve Drain <steve@kappa.me.uk> - 2020-02-25 16:05 +0000
Re: Subtracting times Alan Adams <alan@adamshome.org.uk> - 2020-02-25 16:35 +0000
Re: Subtracting times Steve Drain <steve@kappa.me.uk> - 2020-02-27 17:10 +0000
Re: Subtracting times Steve Drain <steve@kappa.me.uk> - 2020-02-27 10:06 -0800
Re: Subtracting times Alan Adams <alan@adamshome.org.uk> - 2020-02-28 11:21 +0000
Re: Subtracting times jeffrey.a.doggett@gmail.com - 2020-04-22 12:00 -0700
Re: Subtracting times Martin <News03@avisoft.f9.co.uk> - 2020-04-23 00:07 +0100
Re: Subtracting times jeffrey.a.doggett@gmail.com - 2020-04-23 03:13 -0700
Re: Subtracting times Martin <News03@avisoft.f9.co.uk> - 2020-04-23 18:01 +0100
Re: Subtracting times "John Williams (News)" <UCEbin@tiscali.co.uk> - 2020-04-23 18:06 +0100
Re: Subtracting times jeffrey.a.doggett@gmail.com - 2020-04-23 11:18 -0700
Re: Subtracting times Martin <News03@avisoft.f9.co.uk> - 2020-04-23 21:23 +0100
Re: Subtracting times David Higton <dave@davehigton.me.uk> - 2020-04-24 15:24 +0100
Re: Subtracting times David Higton <dave@davehigton.me.uk> - 2020-04-23 20:57 +0100
Re: Subtracting times jgh@mdfs.net - 2020-02-23 17:39 -0800
Re: Subtracting times Steve Drain <steve@kappa.me.uk> - 2020-02-24 10:23 +0000
Re: Subtracting times Alan Adams <alan@adamshome.org.uk> - 2020-02-24 11:12 +0000
Re: Subtracting times Martin <News03@avisoft.f9.co.uk> - 2020-02-24 13:05 +0000
Re: Subtracting times Matthew Phillips <spam2011m@yahoo.co.uk> - 2020-02-19 08:35 +0000
Re: Subtracting times Alan Adams <alan@adamshome.org.uk> - 2020-02-19 10:03 +0000
Re: Subtracting times Sebastian Barthel <naitsabes@freenet.de> - 2020-02-19 13:04 +0000
Re: Subtracting times Alan Adams <alan@adamshome.org.uk> - 2020-02-19 16:41 +0000
Re: Subtracting times jgh@mdfs.net - 2020-02-19 12:01 -0800
Re: Subtracting times Matthew Phillips <spam2011m@yahoo.co.uk> - 2020-02-23 20:46 +0000
Re: Subtracting times Martin <News03@avisoft.f9.co.uk> - 2020-02-19 23:54 +0000
Re: Subtracting times Alan Adams <alan@adamshome.org.uk> - 2020-02-20 11:18 +0000
Page 2 of 2 — ← Prev page 1 [2]
| From | jgh@mdfs.net |
|---|---|
| Date | 2020-02-23 17:39 -0800 |
| Message-ID | <20c98ac0-98f6-4d7a-be0a-8ccaf93e1276@googlegroups.com> |
| In reply to | #5993 |
Alan Adams wrote: > The 5-byte integer values looks correct, but cannot be returned to BASIC. While you can't use the 5-byte integers, you can store and retrieve them with | and hold them in reals, as long as you treat them as opaque values and don't "look" at them. So you can do: |here%=|there% and bar=FNfoo with DEFFNfoo ending with =|somewhere I do this with my Phone library to hold UK telephone numbers in 5-byte objects. jgh
[toc] | [prev] | [next] | [standalone]
| From | Steve Drain <steve@kappa.me.uk> |
|---|---|
| Date | 2020-02-24 10:23 +0000 |
| Message-ID | <r308ag$h4j$1@gioia.aioe.org> |
| In reply to | #5996 |
jgh@mdfs.net wrote: > Alan Adams wrote: >> The 5-byte integer values looks correct, but cannot be returned to BASIC. > > While you can't use the 5-byte integers, you can store and retrieve > them with | and hold them in reals, as long as you treat them as > opaque values and don't "look" at them. So you can do: |here%=|there% > and bar=FNfoo with DEFFNfoo ending with =|somewhere In Basalt time values are held in float variables in just this way, but the manipulation is transparent when used with appropriate keywords. And I, too, have a more-or-less equivalent library in just BASIC. In neither is there a function to satisfy the OP. The nearest is a time difference in seconds, which always fits into an signed integer.
[toc] | [prev] | [next] | [standalone]
| From | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| Date | 2020-02-24 11:12 +0000 |
| Message-ID | <21f8494758.Alan.Adams@ArmX6.adamshome.org.uk> |
| In reply to | #5997 |
In message <r308ag$h4j$1@gioia.aioe.org>
Steve Drain <steve@kappa.me.uk> wrote:
> jgh@mdfs.net wrote:
>> Alan Adams wrote:
>>> The 5-byte integer values looks correct, but cannot be returned to BASIC.
>>
>> While you can't use the 5-byte integers, you can store and retrieve
>> them with | and hold them in reals, as long as you treat them as
>> opaque values and don't "look" at them. So you can do: |here%=|there%
>> and bar=FNfoo with DEFFNfoo ending with =|somewhere
> In Basalt time values are held in float variables in just this way, but
> the manipulation is transparent when used with appropriate keywords.
> And I, too, have a more-or-less equivalent library in just BASIC.
> In neither is there a function to satisfy the OP. The nearest is a time
> difference in seconds, which always fits into an signed integer.
And thank you to all who have contributed. I now have several options to
use. My preference is Martin's, because although all the options return
the time difference in an integer for valid ranges, Martin's returns a
defined -1 to indicate negative or overflow, which helps with the calling
code.
--
Alan Adams, from Northamptonshire
alan@adamshome.org.uk
http://www.nckc.org.uk/
[toc] | [prev] | [next] | [standalone]
| From | Martin <News03@avisoft.f9.co.uk> |
|---|---|
| Date | 2020-02-24 13:05 +0000 |
| Message-ID | <58475466f3News03@avisoft.f9.co.uk> |
| In reply to | #5998 |
On 24 Feb in article <21f8494758.Alan.Adams@ArmX6.adamshome.org.uk>, Alan Adams <alan@adamshome.org.uk> wrote: > My preference is Martin's, because although all the options return > the time difference in an integer for valid ranges, Martin's > returns a defined -1 to indicate negative or overflow, which helps > with the calling code. In in case anyone is interested, I have posted it below. I had to send it direct to Alan because I was away with no csap access. DEF FNsub(A%,B%) = USR tsub% :REM = B% - A% (=> 5 byte times) REM Returns -1 (error) if result negative, REM or over &7fffffff (~35 weeks) .tsub% ; Entry r0 = A% => 5 byte start time (word aligned) lsb..msb ; r1 = B% => 5 byte stop time (word aligned) lsb..msb ; Exit r0 = B%-A% 4 byte time difference or -1 if start after stop ; r0 = r3 - r2 (low word) ; r4 = r6 - r5 (high byte) LDR r2,[r0] ; get low 4 bytes start LDR r3,[r1] ; get low 4 bytes stop LDRB r5,[r0,#4] ; get high byte start LDRB r6,[r1,#4] ; get high byte stop SUBS r0,r3,r2 ; get low bytes difference SBCS r4,r6,r5 ; get high bytes difference - set Z if zero ; r4 = 0 if positive, -1 if negative, else over ~70 weeks Bne error ; TST r0,#1<<31 ; r0 'negative' if over 35 weeks MOVeq pc,r14 ; ok to return positive result .error ; Return error indicator if negative or > ~35 weeks positive MVN r0,#0 ; set return to -1 to indicate error MOV pc,r14 It could be extended, and prbably improved! 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 | Matthew Phillips <spam2011m@yahoo.co.uk> |
|---|---|
| Date | 2020-02-19 08:35 +0000 |
| Message-ID | <757ca84458.Matthew@sinenomine.freeserve.co.uk> |
| In reply to | #5981 |
In message <37f8364458.Alan.Adams@ArmX6.adamshome.org.uk> on 18 Feb 2020 Alan Adams wrote: > My head is hurting. > > I need a BASIC routine to subtract one 5-byte time from another and return > a correctly signed result. > > Complications arise at the point where the low word goes from &7fffffff to > &80000000, and where the high byte increases. > > BASIC doesn't allow access to the carry or borrow from arithmetic > operations. > > I've developed the following which *seems* to work correctly. However I'm > not sure about all the edge cases. I don't think it's doing quite what you want it to do. From the above, my understanding is that you want a signed result, so that if stamp1% is three centiseconds bigger than stamp2% you want a positive number (listing the bytes in memory order): 03 00 00 00 00 and if stamp1% is three centiseconds less than stamp2% you want a negative result: FD FF FF FF FF I also take it that you want a five-byte result, but that in your use case four bytes would always contain the differences. > This is part of a timing system, Next February the high byte of times will > change from &57 to &58, and I would like this code to survive working > across this boundary. I need to reliably detect negative results, which > can occur if a spurious finish time pulse arrives before a start time. > > Subtract stamp2 from stamp1 and store the result in resultbuf. > ( Although the result is 5 bytes. the elapsed time will always be > contained in the low 4 bytes. This will only overflow after 1 year, 5 > months and 2 hours 27 minutes. The system doesn't meed to run for that > long. ) > > PROCsubstamp(resultbuf%,stamp1%,stamp2%) > LOCAL I%,J%,K%,L%,borrow% > borrow%=0 > FOR I%=0 TO3 > J%=stamp1%?I% > K%=stamp2%?I% > L%=J%-K%-borrow% > resultbuf%?I%=L%AND&FF > IF L% < 0 THEN borrow%=1 ELSE borrow%=0 > NEXT > I%=4 > J%=stamp1%?I% > K%=stamp2%?I% > L%=J%-K%-borrow% If you want a signed result, you need to remove the following three lines: > IF L% < 0 THEN > resultbuf%!0 = -(resultbuf%!0) > ENDIF If you want the absolute difference, so that in the above examples of stamp1% and stamp2% differing by 3 centiseconds you would always get 03 00 00 00 00 no matter which of the two was the larger value, you should retain the three lines above but change the following line to resultbuf%?I%=0 But that's only if you're sure the result fits in 4 bytes. > resultbuf%?I%=L%AND&FF > ENDPROC If you wnat a signed result, you can simplify by making the FOR-NEXT loop with I% run from 0 to 4 and lose all the lines after the NEXT. -- Matthew Phillips Durham
[toc] | [prev] | [next] | [standalone]
| From | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| Date | 2020-02-19 10:03 +0000 |
| Message-ID | <4e83b04458.Alan.Adams@ArmX6.adamshome.org.uk> |
| In reply to | #5983 |
In message <757ca84458.Matthew@sinenomine.freeserve.co.uk>
Matthew Phillips <spam2011m@yahoo.co.uk> wrote:
> In message <37f8364458.Alan.Adams@ArmX6.adamshome.org.uk>
> on 18 Feb 2020 Alan Adams wrote:
>> My head is hurting.
>>
>> I need a BASIC routine to subtract one 5-byte time from another and return
>> a correctly signed result.
>>
>> Complications arise at the point where the low word goes from &7fffffff to
>> &80000000, and where the high byte increases.
>>
>> BASIC doesn't allow access to the carry or borrow from arithmetic
>> operations.
>>
>> I've developed the following which *seems* to work correctly. However I'm
>> not sure about all the edge cases.
> I don't think it's doing quite what you want it to do. From the above, my
> understanding is that you want a signed result, so that if stamp1% is
> three centiseconds bigger than stamp2% you want a positive number (listing
> the bytes in memory order):
> 03 00 00 00 00
> and if stamp1% is three centiseconds less than stamp2% you want a negative
> result:
> FD FF FF FF FF
> I also take it that you want a five-byte result, but that in your use case
> four bytes would always contain the differences.
I do want a 4-byte result - the final stage after calling this is
interval%=!resultbuf%. i need this value to be correctly signed.
>> This is part of a timing system, Next February the high byte of times will
>> change from &57 to &58, and I would like this code to survive working
>> across this boundary. I need to reliably detect negative results, which
>> can occur if a spurious finish time pulse arrives before a start time.
>>
<snip>
> If you want a signed result, you need to remove the following three lines:
>> IF L% < 0 THEN
>> resultbuf%!0 = -(resultbuf%!0)
>> ENDIF
That bit is intended to ensure that the 40-byte part is correctly signed.
> If you want the absolute difference, so that in the above examples of stamp1%
> and stamp2% differing by 3 centiseconds you would always get 03 00 00 00 00
> no matter which of the two was the larger value, you should retain the three
> lines above but change the following line to resultbuf%?I%=0
> But that's only if you're sure the result fits in 4 bytes.
If anyone takes a year and a half to paddle round a slalom course, we can
time them with a calendar.
>> resultbuf%?I%=L%AND&FF
>> ENDPROC
> If you wnat a signed result, you can simplify by making the FOR-NEXT loop
> with I% run from 0 to 4 and lose all the lines after the NEXT.
The following shows why this makes my head hurt.
adding two positive numbers shouldn't produce a negative result.
>A%=&7FFFFFFF
>PRINT A%
2.14748365E9
>B%=A%+1
>PRINT B%
-2.14748365E9
>
--
Alan Adams, from Northamptonshire
alan@adamshome.org.uk
http://www.nckc.org.uk/
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Barthel <naitsabes@freenet.de> |
|---|---|
| Date | 2020-02-19 13:04 +0000 |
| Message-ID | <r2jboh$ap3$1@solani.org> |
| In reply to | #5984 |
Am Wed, 19 Feb 2020 10:03:26 +0000 schrieb Alan Adams: > In message <757ca84458.Matthew@sinenomine.freeserve.co.uk> > Matthew Phillips <spam2011m@yahoo.co.uk> wrote: > >> In message <37f8364458.Alan.Adams@ArmX6.adamshome.org.uk> >> on 18 Feb 2020 Alan Adams wrote: > >>> My head is hurting. >>> >>> I need a BASIC routine to subtract one 5-byte time from another and >>> return a correctly signed result. >>> >>> Complications arise at the point where the low word goes from >>> &7fffffff to &80000000, and where the high byte increases. >>> >>> BASIC doesn't allow access to the carry or borrow from arithmetic >>> operations. >> But that's only if you're sure the result fits in 4 bytes. > > If anyone takes a year and a half to paddle round a slalom course, we > can time them with a calendar. > >>> resultbuf%?I%=L%AND&FF >>> ENDPROC > >> If you wnat a signed result, you can simplify by making the FOR-NEXT >> loop with I% run from 0 to 4 and lose all the lines after the NEXT. > > The following shows why this makes my head hurt. > > adding two positive numbers shouldn't produce a negative result. > >>A%=&7FFFFFFF PRINT A% > 2.14748365E9 >>B%=A%+1 PRINT B% > -2.14748365E9 But: that's no problem at all since You are NOT doing some kind of integer mathematics here. You are trying to change the bytes as they are stored in memory. The example with B%=A%+1 results in a "higher" value in memory - but the BASIC interprets it as a signed value, and therefore it changes to negative value if the top-most bit has been set. This only means that You can't print this values directly via PRINT - there is always the need to use an output-procedure if a "time" value is intended. If You really know that the times measured never (!) execeed the 4 Bytes then I dont know why anyone should deal with the highest (the 5th) Byte. If these time stamp%s are taken as start and stop times then they are ordered since You already know wich is the higher/later one. One thing - and thats the first I wanted to mention - more: If this is on a 32 Bit Machine (as an Archimedes or RPC or Pi) then there are only 4 Bytes per integer variable% ! If You use a construct such as stamp1%?I% with I%=4 there will be a result - but probably not the one, wich gives the correct value for the 5th Byte. I think this should give You the least significant Byte of the next 32Bit variable wich is stored in memory directly after (behind) the stamp1% . This means: stamp1%?4 doesn't give the 5th Byte of stamp1% as intendend, but will result in Byte 1 of stamp2% ( hence the same as stamp2%?0 ). All the best, SBn
[toc] | [prev] | [next] | [standalone]
| From | Alan Adams <alan@adamshome.org.uk> |
|---|---|
| Date | 2020-02-19 16:41 +0000 |
| Message-ID | <a8fdd44458.Alan.Adams@ArmX6.adamshome.org.uk> |
| In reply to | #5985 |
In message <r2jboh$ap3$1@solani.org>
Sebastian Barthel <naitsabes@freenet.de> wrote:
> Am Wed, 19 Feb 2020 10:03:26 +0000 schrieb Alan Adams:
>> In message <757ca84458.Matthew@sinenomine.freeserve.co.uk>
>> Matthew Phillips <spam2011m@yahoo.co.uk> wrote:
>>
>>> In message <37f8364458.Alan.Adams@ArmX6.adamshome.org.uk>
>>> on 18 Feb 2020 Alan Adams wrote:
>>
>>>> My head is hurting.
>>>>
>>>> I need a BASIC routine to subtract one 5-byte time from another and
>>>> return a correctly signed result.
>>>>
>>>> Complications arise at the point where the low word goes from
>>>> &7fffffff to &80000000, and where the high byte increases.
>>>>
>>>> BASIC doesn't allow access to the carry or borrow from arithmetic
>>>> operations.
>>> But that's only if you're sure the result fits in 4 bytes.
>>
>> If anyone takes a year and a half to paddle round a slalom course, we
>> can time them with a calendar.
>>
>>>> resultbuf%?I%=L%AND&FF
>>>> ENDPROC
>>
>>> If you wnat a signed result, you can simplify by making the FOR-NEXT
>>> loop with I% run from 0 to 4 and lose all the lines after the NEXT.
>>
>> The following shows why this makes my head hurt.
>>
>> adding two positive numbers shouldn't produce a negative result.
>>
>>>A%=&7FFFFFFF PRINT A%
>> 2.14748365E9
>>>B%=A%+1 PRINT B%
>> -2.14748365E9
> But: that's no problem at all since You are NOT doing some kind of
> integer mathematics here. You are trying to change the bytes as they are
> stored in memory.
> The example with B%=A%+1 results in a "higher" value in memory - but the
> BASIC interprets it as a signed value, and therefore it changes to
> negative value if the top-most bit has been set.
> This only means that You can't print this values directly via PRINT -
> there is always the need to use an output-procedure if a "time" value is
> intended.
The inconsistency is that BASIC shows a number as signed, but treats it in
addition as unsigned. To be consistent it should signal an overflow in the
example above.
> If You really know that the times measured never (!) execeed the 4 Bytes
> then I dont know why anyone should deal with the highest (the 5th) Byte.
> If these time stamp%s are taken as start and stop times then they are
> ordered since You already know wich is the higher/later one.
I don't know which, that's where the problem lies.
Suppose the finisher knocks his button. Then the starter starts someone.
We now have a finish timestamp which is before a start timestamp. To
detect this I need to get the difference returned as a negative number.
The 5th byte becomes important in Februiary 2021. Currently it has the
value &57. Next Feb it moves to &58. I need to ensure that a start with
byte5 as 57 and a finish with a byte5 of 58 doesn't result in a negative
number, nor a ridiculously large one. While it would potentially only
affect a small number of runs, it could also result in a crash somewhere
in the system when presented with invalid data.
> One thing - and thats the first I wanted to mention - more:
> If this is on a 32 Bit Machine (as an Archimedes or RPC or Pi) then there
> are only 4 Bytes per integer variable% !
> If You use a construct such as stamp1%?I% with I%=4 there will be a result
> - but probably not the one, wich gives the correct value for the 5th
> Byte. I think this should give You the least significant Byte of the next
> 32Bit variable wich is stored in memory directly after (behind) the
> stamp1% . This means: stamp1%?4 doesn't give the 5th Byte of stamp1% as
> intendend, but will result in Byte 1 of stamp2% ( hence the same as
> stamp2%?0 ).
I'm not using the 5th byte as part of the answer. I'm using the
calculation of the 5th byte to determine whether to negate the result that
I do use, i.e. bytes 1 to 4. There's no reason in fact to store it after
calculating it - that's left over from some testing situations.
> All the best,
> SBn
--
Alan Adams, from Northamptonshire
alan@adamshome.org.uk
http://www.nckc.org.uk/
[toc] | [prev] | [next] | [standalone]
| From | jgh@mdfs.net |
|---|---|
| Date | 2020-02-19 12:01 -0800 |
| Message-ID | <9c9a0a3d-d0fb-4ae1-966c-90a78889876e@googlegroups.com> |
| In reply to | #5986 |
When I've done this I've manipulated the 5-byte number as two 3-byte numbers, something like: REM time1%=>first 5-byte time REM time2%=>second 5-byte time REM sum% =>7 bytes to hold 5-byte result REM temp1A%=>7 bytes to hold intermediate result REM temp1B%=>7 bytes to hold intermediate result REM temp2A%=>7 bytes to hold intermediate result REM temp2B%=>7 bytes to hold intermediate result : temp1A%!0=time1%!0:temp1A%?3=0 temp1B%!0=time1%!3:temp1B%!5=0 : temp2A%!0=time2%!0:temp2A%?3=0 temp2B%!0=time2%!3:temp2B%!5=0 : sum%!0=temp1A%!0+temp2A%!0 sum%!3=temp1B%!0+temp2B%!0+sum%?3 : (similar for subtraction) The memory use and operations can be optimised, and reading the thread I'd probably go with something like: REM time1%=>first 5-byte time REM time2%=>second 5-byte time REM sum% =>8 bytes to hold 5-byte result sum%!0=0:sum%!4=0 FOR A%=0 TO 4 sum%!A%=time1%?A%+time2%?A%+sum%?A% NEXT A% (similar for subtraction) (I've been staring at that for a while, it looks too simple to be correct!) jgh
[toc] | [prev] | [next] | [standalone]
| From | Matthew Phillips <spam2011m@yahoo.co.uk> |
|---|---|
| Date | 2020-02-23 20:46 +0000 |
| Message-ID | <62b9fa4658.Matthew@sinenomine.freeserve.co.uk> |
| In reply to | #5984 |
In message <4e83b04458.Alan.Adams@ArmX6.adamshome.org.uk>
on 19 Feb 2020 Alan Adams wrote:
> In message <757ca84458.Matthew@sinenomine.freeserve.co.uk>
> Matthew Phillips <spam2011m@yahoo.co.uk> wrote:
>
> > In message <37f8364458.Alan.Adams@ArmX6.adamshome.org.uk>
> > on 18 Feb 2020 Alan Adams wrote:
>
> >> My head is hurting.
> >>
> >> I need a BASIC routine to subtract one 5-byte time from another and return
> >> a correctly signed result.
> >>
> >> Complications arise at the point where the low word goes from &7fffffff to
> >> &80000000, and where the high byte increases.
> >>
> >> BASIC doesn't allow access to the carry or borrow from arithmetic
> >> operations.
> >>
> >> I've developed the following which *seems* to work correctly. However I'm
> >> not sure about all the edge cases.
>
> > I don't think it's doing quite what you want it to do. From the above, my
> > understanding is that you want a signed result, so that if stamp1% is
> > three centiseconds bigger than stamp2% you want a positive number (listing
> > the bytes in memory order):
>
> > 03 00 00 00 00
>
> > and if stamp1% is three centiseconds less than stamp2% you want a negative
> > result:
>
> > FD FF FF FF FF
>
> > I also take it that you want a five-byte result, but that in your use case
> > four bytes would always contain the differences.
>
> I do want a 4-byte result - the final stage after calling this is
>
> interval%=!resultbuf%. i need this value to be correctly signed.
When you say "correctly signed" do you mean that you always want the result
to be positive, so that it expresses the difference in time between stamp1%
and stamp2% regardless of which is the earlier?
Or do you mean that you want the answer to be negative if stamp1% is
earlier than stamp2% and positive if stamp2% is earlier?
I was assuming the latter from your other postings, because you say that you
need to detect the condition of the finisher knocking a button before the
starter starts someone.
If you want the result to be +/- as I had assumed, then you need to get rid
of the bit that says
IF L% < 0 THEN
resultbuf%!0 = -(resultbuf%!0)
ENDIF
That will not be helping. As I said...
> > If you want a signed result, you need to remove the following three
> > lines:
>
> >> IF L% < 0 THEN
> >> resultbuf%!0 = -(resultbuf%!0)
> >> ENDIF
>
> That bit is intended to ensure that the 40-byte part is correctly signed.
You get a correctly signed plus or minus result by just looping through the
five bytes doing the subtraction and borrowing. That is the beauty of
two's-complement representation of negative numbers: exactly the same
operation is done at the byte level no matter whether it is signed or
unsigned arithmentic. The only difference is in the detection of carrying or
overflow. You've already made it clear that the times you are dealing with a
relatively close to each other (within a day or two, say) so you will not get
any overflow from subtracting them and the top byte can be ignored
completely.
> The following shows why this makes my head hurt.
>
> adding two positive numbers shouldn't produce a negative result.
>
> >A%=&7FFFFFFF
> >PRINT A%
> 2.14748365E9
> >B%=A%+1
> >PRINT B%
> -2.14748365E9
Well, that's a quirk of BBC BASIC that we were discussing a few weeks ago.
BASIC stupidly, in my opinion, allows you to do arithmetic on signed values
without warning about overflows.
I suggest you use:
PROCsubstamp(resultbuf%,stamp1%,stamp2%)
LOCAL I%,J%,K%,L%,borrow%
borrow%=0
FOR I%=0 TO3
J%=stamp1%?I%
K%=stamp2%?I%
L%=J%-K%-borrow%
resultbuf%?I%=L%AND&FF
IF L% < 0 THEN borrow%=1 ELSE borrow%=0
NEXT
ENDPROC
And then your answer can be read from !resultbuf% as a 4-byte signed value.
This will only work if the two timestamps are within 497 days of each other.
You are probably worried what will happen when we have these two timestamps:
A: 57FFFFFFFF
B: 5800000000
B is one centisecond higher than A.
Take FF off 0 and we get 1, borrow one.
Take FF and a borrow off 0 and we get 0
Take FF and a borrow off 0 and we get 0
Take FF and a borrow off 0 and we get 0
Take 57 and a borrow off 58 and we also get 0, but you're only looping from 0
to 3 so we don't even calculate this bit.
Therefore you get the answer 00000001 which is what you want.
Similarly if you take B off A, you will get FFFFFFFF which is -1 and is
correct.
If you know your answer is always going to fit in 4 bytes, just ditch all the
code after the end of your FOR-NEXT loop.
--
Matthew Phillips
Durham
[toc] | [prev] | [next] | [standalone]
| From | Martin <News03@avisoft.f9.co.uk> |
|---|---|
| Date | 2020-02-19 23:54 +0000 |
| Message-ID | <5844fc97edNews03@avisoft.f9.co.uk> |
| In reply to | #5981 |
On 18 Feb in article <37f8364458.Alan.Adams@ArmX6.adamshome.org.uk>, Alan Adams <alan@adamshome.org.uk> wrote: > I need a BASIC routine to subtract one 5-byte time from another and > return a correctly signed result. Can it be assumed that both 5-byte times are work aligned? -- 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-02-20 11:18 +0000 |
| Message-ID | <2c383b4558.Alan.Adams@ArmX6.adamshome.org.uk> |
| In reply to | #5989 |
In message <5844fc97edNews03@avisoft.f9.co.uk>
Martin <News03@avisoft.f9.co.uk> wrote:
> On 18 Feb in article <37f8364458.Alan.Adams@ArmX6.adamshome.org.uk>,
> Alan Adams <alan@adamshome.org.uk> wrote:
>> I need a BASIC routine to subtract one 5-byte time from another and
>> return a correctly signed result.
> Can it be assumed that both 5-byte times are work aligned?
As the buffers are created with DIM, I believe they are aligned.
--
Alan Adams, from Northamptonshire
alan@adamshome.org.uk
http://www.nckc.org.uk/
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.sys.acorn.programmer
csiph-web