Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.sys.acorn.programmer > #5981 > unrolled thread

Subtracting times

Started byAlan Adams <alan@adamshome.org.uk>
First post2020-02-18 11:55 +0000
Last post2020-02-20 11:18 +0000
Articles 12 on this page of 32 — 10 participants

Back to article view | Back to comp.sys.acorn.programmer


Contents

  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]


#5996

Fromjgh@mdfs.net
Date2020-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]


#5997

FromSteve Drain <steve@kappa.me.uk>
Date2020-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]


#5998

FromAlan Adams <alan@adamshome.org.uk>
Date2020-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]


#5999

FromMartin <News03@avisoft.f9.co.uk>
Date2020-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]


#5983

FromMatthew Phillips <spam2011m@yahoo.co.uk>
Date2020-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]


#5984

FromAlan Adams <alan@adamshome.org.uk>
Date2020-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]


#5985

FromSebastian Barthel <naitsabes@freenet.de>
Date2020-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]


#5986

FromAlan Adams <alan@adamshome.org.uk>
Date2020-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]


#5988

Fromjgh@mdfs.net
Date2020-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]


#5995

FromMatthew Phillips <spam2011m@yahoo.co.uk>
Date2020-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]


#5989

FromMartin <News03@avisoft.f9.co.uk>
Date2020-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]


#5990

FromAlan Adams <alan@adamshome.org.uk>
Date2020-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