*Post by Alan Adams**Post by Matthew Phillips**Post by Alan Adams*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

03 00 00 00 00

and if stamp1% is three centiseconds less than stamp2% you want a negative

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...

*Post by Alan Adams**Post by Matthew Phillips**Post by Alan Adams*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.

*Post by Alan Adams*The following shows why this makes my head hurt.

adding two positive numbers shouldn't produce a negative result.

2.14748365E9

-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