The preservation of numerical precision
A customer reported a difference in behavior when executing some code in the design time and in a COM dll.
You can run this code to see it: (use the server created from https://blogs.msdn.com/calvin_hsia/archive/2004/06/18/159550.aspx)
?SET("Decimals")
SET DECIMALS TO 15
num=12.45678901234567890
?num
ox=CREATEOBJECT("t1.c1")
*ox.mydocmd("set decimals to 15")
?ox.myeval("p2",num) && just evaluate the parameter and return it
The code creates a real number, prints it, then just passes it to the COM server, which just returns it so it’s printed again.
The output is:
12.45678901234567890
12.4567890123
It appears that some precision has been lost.
Internally, VFP keeps track of how much we know about a real number. This can be easily shown by running this code:
SET DECIMALS TO 15
?1.2
?1.20
?1.2000
Indeed, we can demonstrate that the precision of mathematical calculations is propagated from the precision of the operands.
ShowStuff(1.2)
ShowStuff(1.20)
ShowStuff(1.200)
ShowStuff(1.2000)
ShowStuff(1.20000)
PROCEDURE ShowStuff(n as Number)
?n, n*2,n*2.0,n*2.00
RETURN
1.2 2.4 2.40 2.400
1.20 2.40 2.400 2.4000
1.200 2.400 2.4000 2.40000
1.2000 2.4000 2.40000 2.400000
1.20000 2.40000 2.400000 2.4000000
Try this code to see how VFP uses the DECIMALS setting in calculations. It sums 1/3 j times and compares that with j/3
tryit(2)
tryit(12)
PROCEDURE tryit(nDec as Integer)
SET DECIMALS TO (nDec)
?"Decimals",SET("Decimals")
x=3
FOR j = 46190 TO 46195 STEP 1
s=0
num=3 *j
FOR i = 1 TO num
s=s+1/x
ENDFOR
?j,num/3,s,s=num/3
ENDFOR
RETURN
The propagation of precision reminds me of something closely related: probable error propagation.
When I was in physics class in the mid 70’s, I learned about probable error and how to manipulate it. The probable error (PE) is often expressed as a Plus or Minus (±) after a measurement.
For example, if you measure a square object, you might come up with a measurement of 12 ± 1.2 units (± 10 %). The perimeter can be calculated by multiplying by 4, resulting in 48. The probable error is sqrt(4*(1.2)^2) = 2.4
For more information about probable error and measurement uncertainty, and how they propagate through calculation, see Error Analysis
Comments
- Anonymous
November 01, 2006
Calvin, since I installed IE 7.0 your BLOG crawler isn't storing the web pages correctly. It still shows all the items stored when IE 6.0 was installed, just not the new ones (10/19 and 10/24). Rick