Wednesday, May 30, 2012

A Clarification on SAS mod function.

I am a long term SAS fan.  Its statistical functions and powerful macro scripting capability are simply unprecedented.  There is a little bit of misunderstanding concerning my post on MOD function.  The following is a clarification from Rick Langston from SAS.

Rick's clarification follows.
There is no such "bug" in the MOD function in SAS.
The problem is due to the limitation of IEEE floating point
representation with the number of digits used in the example.
The number 11169568236203649 cannot be precisely stored in a 64-bit
IEEE floating point value. It is indistinguishable from
11169568236203648, for example.
SAS uses floating point representation for all of its numeric values.
Note that if you apply the same constraints to databases, you
will see the same results as SAS. For example, on Teradata
if you submit this expression:

select cast(11169568236203649 as float) mod cast(30269 as float);
You get the response of
        1.17310000000000E 004
Which is just what SAS provides.

And consider this C code:
double x;
x = (long long)11169568236203649.0 % (long long)30269.0;
x = 11169568236203649LL % 30269LL;

The results are this:

It's the same issue. The double-precision value cannot
be represented sufficiently. If the value remains as a long
integer, the representation is maintained.

Note also that when you run the same MOD function example on
z/OS (i.e. IBM mainframe), you get 11732. This is because the
IBM floating point representation has 4 more bits of mantissa
(at the expense of 4 less bits of exponent) than does IEEE. So
more digits of precision will be noticed, as is the case with the

It had been commented that 64-bit systems might make a difference,
such as SAS on 64-bit Windows as compared to 32-bit Windows.
That is not the case here. The IEEE floating point representation
used by SAS is 64-bit on all platforms. Only the z/OS implementation
of SAS uses the IBM representation.
End of Rick's clarification

No comments: