It is well known that floating point numbers can sometimes produce surprising results. For example most of us have witnessed the result of dividing 1 by 3 on a hand-held calculator. Digits that the calculator can not store are just discarded. Thus, it is possible to have two different REAL numbers whose 15 digit decimal representations appear the same, but when compared or subtracted they are NOT. If not anticipated, it can be a difficult programming "bug" to unravel. Also, since REAL numbers are only a subset of the rational numbers, some operations produce an overflow or underflow error. For example:
RAD
One = COS(3)*COS(3)+SIN(3)*SIN(3)
PRINT One,One-1.0
From trigonometry, the variable One should equal 1. And indeed, when One is printed, we see it is "1", but the value printed for One-1.0 is not zero but a very small number.
Comparing REALs
Rather than compare two REAL values for equality, it is often best to compare them for an acceptably small difference. For example:
IF ABS(One-1.0) < 1E-15 THEN PRINT "EQUAL ENOUGH"
Alternately, DROUND or PROUND can be used to round the binary representations to match each other:
PRINT One,DROUND(One,1)-DROUND(1.0,1)
In FOR Loops
It may not be a good idea to use a REAL variable in a FOR loop with a small STEP as rounding errors can accumulate:
FOR X=1 TO -1 STEP -.05
PRINT X;TAB(20);ACS(X)
NEXT X
This loop never gets to -1 as expected due to the accumulation of rounding errors with the small STEP value.
An INTEGER should instead be used for the loop counter so that the number of iterations can then be specified exactly and X can be incremented separately:
INTEGER I
FOR I=0 TO 40
X=1-I*.05
PRINT X;TAB(20);ACS(X)
NEXT I
Formal Definition
The exact subset of rational numbers that can be represented by REAL numbers is: (-1)s * 2e * mantissa, where:
s = 0 or 1.
e = any integer between -1022 and +1023.
mantissa = b0 * 2-0 + b1 * 2-1 + ... + b52 * 2-52
b0 = 1
bi = 0 or 1 (for i<>0)