Hi,
I looked into this a bit further and it appears that be behavior I observed is unique to SAS 9.4_M6 (as others already commented that they can't replicate on other version). I rerun the same code on with 9.4_M7 and I got the expected behavior (the difference is 0).
More specifically, in 9.4_M6, I have this behavior (I promise this is a different screenshot from before, I just rerun the thing again):
The same code with 9.4_M7:
For what little it may mean, I get the expected appearance of 0 for both X and Y using SAS 9.4m4.
Please send the code and those images of 9.4M6 and 9.4M7 in to tech support. Maybe they can explain and document this bug (assuming they agree it's a bug...)
I am in Technical Support. I am sorry I led you down the path of numeric precision when that isn't exactly the issue here. I am running the exact same version of 9.4M6 as you:
13 %put &sysvlong;
9.04.01M6P110718
and I am not replicating the same difference that you show.
While the behavior does seem strange and incorrect, the fact that we cannot replicate it in the same version and the fact that it does not appear to occur in later releases suggests that it would not be treated as a bug for M6. Ultimately, the way to account for the difference when using imprecise values is to use the ROUND function.
Since you are running on Windows 32-bit, the following SAS Note might provide some additional explanation:
6214 - Similar equations yield different results on Intel machines
If you would like to continue to pursue this through a case with Technical Support, please feel free to open a new one and include your complete log and output.
Thanks @Kathryn_SAS , that tech support note looks like exactly this problem. Very interesting. I tend to think in terms of the (logical) PDV, without worrying about registers and memory locations. Very interesting to see the explanation in that note.
Thanks very much to everyone in this thread who has investigated the issue or attempted to replicate the issue on their own machine. I got pulled away and am just now going through the responses.
FYI, FoxHope is my coworker, so both of us have the same version of SAS installed on our machines.
Kathryn, thanks for checking on this issue. The SAS note you referenced seems to explain this issue, at least in part. Here is the version of SAS I am running:
354 %put &sysvlong;
9.04.01M6P111518
Just for fun, what happens in M6 if you do:
r = m-n;
s = m-n;
t = m-n;
u = m-n;
and what about:
* r = m-n;
s = m-n;
t = m-n;
u = m-n;
And adding that PUT statement fixes the problem in M6? That's a crazy part of the puzzle.
I will consider sending a ticket to support later today. Seeing others not being able to replicate these results is making me doubt my own sanity lol. But otherwise, for funsies, happy to oblige with some experiments.
More subtractions:
Remove r = m-n
Replace value of n to 1/3 from 1/a (notice the sign change for r). This makes me thing that assigning a = 3 has some thing to do with this.
Lastly, outputting the values to log does fix the problem only if the values were written to log before r is calculated.
Same thing but different order
Looks like a Heisenbug. The addition of the PUT changes something which causes the bug to vanish.?
Hi @twedwards and @FoxHope,
Thank you for providing evidence that this phenomenon still occurs with recent SAS versions. I observed it in May 2012 when I worked on a freelance project at a pharma company. My documentation indicates that it occurred with SAS 9.2 TS2M3 on their Windows 2008 server, but not on their Unix server. Interestingly, that Windows Server 2008 was a 32-bit operating system (the "W32_SRV08 platform"), which might be crucial for this issue.
Here is an example that I documented back then:
data test; a=0.1; b=0.7; c=a+b; d=0.8; e=d-c; f=d-c; proc print; run; Result (from May 2012): Obs A B C D E F 1 0.1 0.7 0.8 0.8 8.3267E-17 1.1102E-16
As in your examples, it was always only the first of two or more identical calculations which had an unexpected result. The result in variable F was the expected "classic numeric precision" issue, a rounding error in the least significant bit, which can be explained in detail by performing the calculation in the binary system according to the IEEE 754 standard. Only the result in E was surprising. (One of the striking consequences of the issue was that, after defining
a=0.1; b=0.7; c=a+b; d=0.8;
the seemingly exhaustive IF condition
d-c>1e-16 | d-c<1e-16 | d-c=1e-16
was not met, presumably because the result of d-c changed from 8.3267E-17 in the first part to 1.1102E-16 in the second and third part of the Boolean expression!)
Today, my SAS 9.4M5 on a 64-bit Windows workstation yields 1.1102E-16 in both variables, E and F, as expected. Similarly, it yields correctly 0 in your examples.
I agree with you and @Quentin that this looks very much like what is described in the Usage Note 6214 (which I wasn't aware of back in 2012) linked by @Kathryn_SAS.
A strong indication that it has to do with those "12 extra bits for the mantissa" (in FPU registers or somewhere else in the processor) mentioned in that Usage Note is this: The least significant bit of the internal 64-bit floating-point representation of 1/3 in a numeric variable (under Windows or Unix, including 32-bit platforms) has a place value of 2**-54=5.5511...E-17. Therefore, any "classic" numeric precision issue involving numbers close to 1/3 (namely >=0.25 and <0.5) can only create differences which are integer multiples of 2**-54. The absolute value of your example difference r=-1.8513E-17, however, is obviously less than that. In fact, it is close to one third of 2**-54 (1.85037...E-17) and an internal binary representation of it would require at least 11 additional mantissa bits: -683*2**-65 = -1.85127520951899882...E-17.
I would be curious if your difference r in BEST32. format looks like -1.851275209519E-17 and, even more precisely, like BC75580000000000 in HEX16. format.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.