4 ms·
There was recently an interesting thread on the Retro Computing Forum [1] related to this and curious behavior in 6502 flavors of MS BASIC. In brief, the condit
by masswerk 3y ago
There was recently an interesting thread on the Retro Computing Forum [1] related to this and curious behavior in 6502 flavors of MS BASIC. In brief, the condition in
IF SQR(3 * 2) = SQR(3) * SQR(2) THEN…
evaluates to false, while,
IF SQR(3 * 2) - SQR(3) * SQR(2) = 0 THEN…
evaluates to true. Similarly,
A = SQR(3 * 2) - SQR(3) * SQR(2)
assigns zero (0.0) to variable A. So,
SQR(3 * 2) <> SQR(3) * SQR(2)
but
SQR(3 * 2) - SQR(3) * SQR(2) = 0
Which is kind of a nice paradox. (The same is true for a variety of other value combinations.) We learn, the value of an expression in a comparison is not the same as its result (probably due to result cleanup, especially, when the exponent happens to be zero.)
[1] https://retrocomputingforum.com/t/investigating-basic-floating-point-accuracy-and-finding-a-bug/3588 https://retrocomputingforum.com/t/investigating-basic-floati...
- lmm 3y ago> We learn, the value of an expression in a comparison is not the same as its result (probably due result cleanup, especially, when the exponent happens to be zero.) That happens all the time on traditional x86 - (non-SSE) floating point registers are 80 bits and then (usually) get rounded to 64 bits when you store them in memory, so you will very often have an expression that's nonzero if you use it immediately, but zero if you put it in a variable and use it later.
- masswerk 3y agoIn this case, there are two mechanisms at work: a conventional rounding bit (for each of the two floating point accumulators available), and a special routine, which zeros out all bytes of the floating point accumulator, when the result is transferred and the exponent is zero. I personally suspect that it's the latter, which is not triggered appropriately and which seems to be the culprit here. Notably, this routine only applies to the first of these accumulators. (It seems, though, that the routine should be called, when a value is copied from one FAC to the other, which we would expect here to happen. So I'm not sure.) (The precision, BTW, is 4 bytes mantissa including a sign bit, and one byte exponent with a bias of 127. The floating point accumulators extract the sign to an extra byte, but there is no change in precision with regard to the storage format, other than said rounding bit. At least, this is what it's in Commodore BASIC, the flavor I'm most familiar with. Apple ][ BASIC should be pretty much the same, as it's closely related. And, notably, the 6502 processor only provides addition and subtraction for single-byte values, everything else has to be done in software. So there's no extra precision in any processor register, either.)