I was asked about floating point calculations. In particular, I can write code like this:
?”This code will execute if result = 34″
*Output is 34.0 .T.
If you add 3 zeros to x (change x to 3.4000) then
*Output is 34.0000 .T.
Fox is keeping track internally of not only the floating point value of a number, but the number of decimal points of accuracy (I’ll call that NUMDPS). “3.4” has 1 implied decimal place of accuracy. “3.4000” has 4. When doing operations on a floating point number, the NUMDPS are tracked too. For example, when multiplying 2 floating point numbers, NUMDPS is the sum of the NUMDPS of the multiplicands. For addition, NUMDPS is the larger of the NUMDPS of the addends.
Floating point numbers are represented internally in binary. Run the BINTOC sample that ships with VFP to see the actual binary representation: Start VFP, choose Tools->Task Pane->Solution Samples->New in VFP9->BINTOC Binary Conversion
Type in 3.4 and choose “B” as the parameter to BINTOC.
It shows that 3.4 is represented internally as 33 33 33 33 33 33 08 40 hex, or 0011:0011 0011:0011 0011:0011 0011:0011 0011:0011 0011:0011 0000:1011 0100:0000 in binary
In fact, any multiple of 1/10 is an infinitely repeating fraction in binary. Just as 1/3 = .33333333333 in base 10, repeated fractions are not exact.
So what if you add 1/3 3 times?
.9999999 which is not exactly equal to 1.
So how is it that Fox says the result is equal to 34 ?
In general, to see if 2 values are equal, subtract one from the other, take the absolute value, and see if you get zero. This works fine for integers, but for real numbers, we may not get exactly zero.
We need then to determine how close to zero is close enough? Close enough means smaller than some number (often called epsilon) that is acceptable.
For acceptability we need to consider how many decimal places of accuracy are known.
If we get 34 – 33.9999999999 = 1E-10, and we only have 1 decimal digit of accuracy then we are clearly willing to accept that 1E-10 is indeed zero.
However, 34.000000000000 – 33.9999999999 = 1E-10 and we now have 10 digits of accuracy and it’s not so clear if this is close enough to zero.
Fox internally has an array of floats: 0.5E0, 0.5E-1, 0.5E-2, 0.5E-3, 0.5E-4, 0.5E-5, 0.5E-6, 0.5E-7, 0.5E-8 etc. NUMDPS is an index into this array to look up an appropriate epsilon to use.