DATA Step, Macro, Functions and more

Expected numeric precision behaviour or unexpected issue?

Posts: 2,348

Expected numeric precision behaviour or unexpected issue?

[ Edited ]

SAS (WIN9.4) thinks 0.5 is not always equal to 0.5 depending on how it's written.


data TEST;
  %macro loop;
    %do i=0 %to 50;
      NB = 0.5%sysfunc(repeat(0,&i));
      put NB hex16. " L=&i NB=0.5%sysfunc(repeat(0,&i))";



3FE0000000000000 L=0 NB=0.50

3FE0000000000000 L=1 NB=0.500

3FE0000000000000 L=2 NB=0.5000

3FE0000000000000 L=3 NB=0.50000

3FE0000000000000 L=4 NB=0.500000

3FE0000000000000 L=5 NB=0.5000000

3FE0000000000000 L=6 NB=0.50000000

3FE0000000000000 L=7 NB=0.500000000

3FE0000000000000 L=8 NB=0.5000000000

3FE0000000000000 L=9 NB=0.50000000000

3FE0000000000000 L=10 NB=0.500000000000

3FE0000000000000 L=11 NB=0.5000000000000

3FE0000000000000 L=12 NB=0.50000000000000

3FE0000000000000 L=13 NB=0.500000000000000

3FE0000000000000 L=14 NB=0.5000000000000000

3FE0000000000000 L=15 NB=0.50000000000000000

3FE0000000000000 L=16 NB=0.500000000000000000

3FE0000000000000 L=17 NB=0.5000000000000000000

3FE0000000000000 L=18 NB=0.50000000000000000000

3FE0000000000000 L=19 NB=0.500000000000000000000

3FE0000000000000 L=20 NB=0.5000000000000000000000

3FE0000000000000 L=21 NB=0.50000000000000000000000

3FE0000000000000 L=22 NB=0.500000000000000000000000

3FDFFFFFFFFFFFFE L=23 NB=0.5000000000000000000000000

3FDFFFFFFFFFFFFE L=24 NB=0.50000000000000000000000000

3FDFFFFFFFFFFFFF L=25 NB=0.500000000000000000000000000

3FE0000000000000 L=26 NB=0.5000000000000000000000000000

3FE0000000000000 L=27 NB=0.50000000000000000000000000000

3FDFFFFFFFFFFFFF L=28 NB=0.500000000000000000000000000000

3FDFFFFFFFFFFFFF L=29 NB=0.5000000000000000000000000000000

3FE0000000000000 L=30 NB=0.50000000000000000000000000000000

3FE0000000000000 L=31 NB=0.500000000000000000000000000000000

3FE0000000000000 L=32 NB=0.5000000000000000000000000000000000

3FE0000000000000 L=33 NB=0.50000000000000000000000000000000000

3FE0000000000000 L=34 NB=0.500000000000000000000000000000000000

3FE0000000000000 L=35 NB=0.5000000000000000000000000000000000000

3FE0000000000000 L=36 NB=0.50000000000000000000000000000000000000

3FE0000000000000 L=37 NB=0.500000000000000000000000000000000000000

3FE0000000000000 L=38 NB=0.5000000000000000000000000000000000000000

3FE0000000000000 L=39 NB=0.50000000000000000000000000000000000000000

3FE0000000000000 L=40 NB=0.500000000000000000000000000000000000000000

3FE0000000000000 L=41 NB=0.5000000000000000000000000000000000000000000

3FE0000000000000 L=42 NB=0.50000000000000000000000000000000000000000000

3FE0000000000000 L=43 NB=0.500000000000000000000000000000000000000000000

3FE0000000000000 L=44 NB=0.5000000000000000000000000000000000000000000000

3FE0000000000000 L=45 NB=0.50000000000000000000000000000000000000000000000

3FE0000000000000 L=46 NB=0.500000000000000000000000000000000000000000000000

3FE0000000000000 L=47 NB=0.5000000000000000000000000000000000000000000000000

3FE0000000000000 L=48 NB=0.50000000000000000000000000000000000000000000000000

3FE0000000000000 L=49 NB=0.500000000000000000000000000000000000000000000000000

3FE0000000000000 L=50 NB=0.5000000000000000000000000000000000000000000000000000



As you can see, this number is stored as 3FE0000000000000 except when L is 23 to 29, where it is sometimes stored as 3FDFFFFFFFFFFFFE  or 3FDFFFFFFFFFFFFF.


I reckon this should not be taking place as trailing zeros are not significant.

The trailing zeros are even less significant (than not significant!) since the trailing zeros causing the issue are well beyond the 16-digit precision offered by SAS.


So what do you think? Expected numeric precision (mis)behaviour or unexpected issue?

I lean towards the second option.


Note that this matters as the odd behaviour happens at lengths below 32, which means that formatted values (coming for example from macro variables) will match or not depending on the format used.



Esteemed Advisor
Posts: 5,524

Re: Expected numeric precision behaviour or unexpected issue?

On 32 bit SAS, the problem occurs at L=23 only.


165  data TEST;
166    %macro loop;
167      %do i=0 %to 50;
168        NB = 0.5%sysfunc(repeat(0,&i));
169        V = NB = 0.5;
170        put NB hex16. V 2. " L=&i NB=0.5%sysfunc(repeat(0,&i))";
171      %end;
172    %mend;
173    %loop;
174  run;

3FE0000000000000 1 L=0 NB=0.50
3FE0000000000000 1 L=1 NB=0.500
3FE0000000000000 1 L=2 NB=0.5000
3FE0000000000000 1 L=3 NB=0.50000
3FE0000000000000 1 L=4 NB=0.500000
3FE0000000000000 1 L=5 NB=0.5000000
3FE0000000000000 1 L=6 NB=0.50000000
3FE0000000000000 1 L=7 NB=0.500000000
3FE0000000000000 1 L=8 NB=0.5000000000
3FE0000000000000 1 L=9 NB=0.50000000000
3FE0000000000000 1 L=10 NB=0.500000000000
3FE0000000000000 1 L=11 NB=0.5000000000000
3FE0000000000000 1 L=12 NB=0.50000000000000
3FE0000000000000 1 L=13 NB=0.500000000000000
3FE0000000000000 1 L=14 NB=0.5000000000000000
3FE0000000000000 1 L=15 NB=0.50000000000000000
3FE0000000000000 1 L=16 NB=0.500000000000000000
3FE0000000000000 1 L=17 NB=0.5000000000000000000
3FE0000000000000 1 L=18 NB=0.50000000000000000000
3FE0000000000000 1 L=19 NB=0.500000000000000000000
3FE0000000000000 1 L=20 NB=0.5000000000000000000000
3FE0000000000000 1 L=21 NB=0.50000000000000000000000
3FE0000000000000 1 L=22 NB=0.500000000000000000000000
3FDFFFFFFFFFFFFF 0 L=23 NB=0.5000000000000000000000000
3FE0000000000000 1 L=24 NB=0.50000000000000000000000000
3FE0000000000000 1 L=25 NB=0.500000000000000000000000000
3FE0000000000000 1 L=26 NB=0.5000000000000000000000000000
3FE0000000000000 1 L=27 NB=0.50000000000000000000000000000
3FE0000000000000 1 L=28 NB=0.500000000000000000000000000000
3FE0000000000000 1 L=29 NB=0.5000000000000000000000000000000
3FE0000000000000 1 L=30 NB=0.50000000000000000000000000000000
3FE0000000000000 1 L=31 NB=0.500000000000000000000000000000000
3FE0000000000000 1 L=32 NB=0.5000000000000000000000000000000000
3FE0000000000000 1 L=33 NB=0.50000000000000000000000000000000000
3FE0000000000000 1 L=34 NB=0.500000000000000000000000000000000000
3FE0000000000000 1 L=35 NB=0.5000000000000000000000000000000000000
3FE0000000000000 1 L=36 NB=0.50000000000000000000000000000000000000
3FE0000000000000 1 L=37 NB=0.500000000000000000000000000000000000000
3FE0000000000000 1 L=38 NB=0.5000000000000000000000000000000000000000
3FE0000000000000 1 L=39 NB=0.50000000000000000000000000000000000000000
3FE0000000000000 1 L=40 NB=0.500000000000000000000000000000000000000000
3FE0000000000000 1 L=41 NB=0.5000000000000000000000000000000000000000000
3FE0000000000000 1 L=42 NB=0.50000000000000000000000000000000000000000000
3FE0000000000000 1 L=43 NB=0.500000000000000000000000000000000000000000000
3FE0000000000000 1 L=44 NB=0.5000000000000000000000000000000000000000000000
3FE0000000000000 1 L=45 NB=0.50000000000000000000000000000000000000000000000
3FE0000000000000 1 L=46 NB=0.500000000000000000000000000000000000000000000000
3FE0000000000000 1 L=47 NB=0.5000000000000000000000000000000000000000000000000
3FE0000000000000 1 L=48 NB=0.50000000000000000000000000000000000000000000000000
3FE0000000000000 1 L=49 NB=0.500000000000000000000000000000000000000000000000000
3FE0000000000000 1 L=50 NB=0.5000000000000000000000000000000000000000000000000000
Posts: 2,348

Re: Expected numeric precision behaviour or unexpected issue?

Good point. Running 64bits.

Super User
Super User
Posts: 8,089

Re: Expected numeric precision behaviour or unexpected issue?

Exactly what version of SAS are you running?  It does not do it in Linux with 9.4 (TS1M3).


Super User
Posts: 3,918

Re: Expected numeric precision behaviour or unexpected issue?

I get the same as @ChrisNZ on 64-bit Windows SAS 9.4TS1M2 and SAS 9.4TS1M3.

Posts: 2,348

Re: Expected numeric precision behaviour or unexpected issue?

The fact that we have three different results on three OSes makes me lean even more toward the defect option.



Super User
Posts: 10,217

Re: Expected numeric precision behaviour or unexpected issue?

Just ran your code on SAS 9.2, 64 bit, AIX.

No error at all, consistent data throughout.

Suggestion: Trash the sucky pseudo-OS Windows and get a real one for your SAS server.

Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Posts: 2,348

Re: Expected numeric precision behaviour or unexpected issue?

Posted in reply to KurtBremser

@KurtBremser I wish I could Kurt, I wish I could....

Super Contributor
Posts: 394

Re: Expected numeric precision behaviour or unexpected issue?

This is a recurring topic. Here's good information about numerical accuracy in SAS programs.

Super User
Posts: 10,217

Re: Expected numeric precision behaviour or unexpected issue?

AFAIK, precision-related problems should be the same with SAS on UNIX and Windows. But, as demonstrated here, they are not.

The fact that the problem here seems only to be present on Windows (as Linux and AIX based SAS versions don't show it), the problem is either in WIndows itself or in the Windows build of SAS.

Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Posts: 2,348

Re: Expected numeric precision behaviour or unexpected issue?

@Tim_SASThe link you provide does not address this issue presented here, Tim.

Hence my question's title.

As @Astounding points out, 0.5 can be represented in binary format as 3FE0000000000000x.

The issue is that SAS reads code/text containing non-significant decimals in a weird (and as it turns out inconsistent across platforms) manner.

Super Contributor
Posts: 394

Re: Expected numeric precision behaviour or unexpected issue?

You're right. I replied too quickly. That's what I get for reading SAS Communities before I've had my coffee.

Super User
Posts: 6,762

Re: Expected numeric precision behaviour or unexpected issue?

To me, this is especially shocking because there shouldn't be any numeric precision involved.  0.5 is a number that can be stored exactly in a binary system, as 0.1 where the first position after the decimal point is the halves column.

Super User
Super User
Posts: 8,089

Re: Expected numeric precision behaviour or unexpected issue?

Report it as a bug to SAS Support.

It doesn't seem to impact the INPUT() function. Just the interpretation of numeric literals in the code statements.


Posts: 2,348

Re: Expected numeric precision behaviour or unexpected issue?

[ Edited ]

No issue on mainframe either.



4080000000000000 L=0 NB=0.50

4080000000000000 L=1 NB=0.500

4080000000000000 L=2 NB=0.5000

4080000000000000 L=3 NB=0.50000

4080000000000000 L=4 NB=0.500000

4080000000000000 L=5 NB=0.5000000

4080000000000000 L=6 NB=0.50000000

4080000000000000 L=7 NB=0.500000000

4080000000000000 L=8 NB=0.5000000000

4080000000000000 L=9 NB=0.50000000000

4080000000000000 L=10 NB=0.500000000000

4080000000000000 L=11 NB=0.5000000000000

4080000000000000 L=12 NB=0.50000000000000

4080000000000000 L=13 NB=0.500000000000000

4080000000000000 L=14 NB=0.5000000000000000

4080000000000000 L=15 NB=0.50000000000000000

4080000000000000 L=16 NB=0.500000000000000000

4080000000000000 L=17 NB=0.5000000000000000000

4080000000000000 L=18 NB=0.50000000000000000000

4080000000000000 L=19 NB=0.500000000000000000000

4080000000000000 L=20 NB=0.5000000000000000000000

4080000000000000 L=21 NB=0.50000000000000000000000

4080000000000000 L=22 NB=0.500000000000000000000000

4080000000000000 L=23 NB=0.5000000000000000000000000

4080000000000000 L=24 NB=0.50000000000000000000000000

4080000000000000 L=25 NB=0.500000000000000000000000000

4080000000000000 L=26 NB=0.5000000000000000000000000000

4080000000000000 L=27 NB=0.50000000000000000000000000000

4080000000000000 L=28 NB=0.500000000000000000000000000000

4080000000000000 L=29 NB=0.5000000000000000000000000000000

4080000000000000 L=30 NB=0.50000000000000000000000000000000

4080000000000000 L=31 NB=0.500000000000000000000000000000000

4080000000000000 L=32 NB=0.5000000000000000000000000000000000

4080000000000000 L=33 NB=0.50000000000000000000000000000000000

4080000000000000 L=34 NB=0.500000000000000000000000000000000000

4080000000000000 L=35 NB=0.5000000000000000000000000000000000000

4080000000000000 L=36 NB=0.50000000000000000000000000000000000000

4080000000000000 L=37 NB=0.500000000000000000000000000000000000000

4080000000000000 L=38 NB=0.5000000000000000000000000000000000000000

4080000000000000 L=39 NB=0.50000000000000000000000000000000000000000

4080000000000000 L=40 NB=0.500000000000000000000000000000000000000000

4080000000000000 L=41 NB=0.5000000000000000000000000000000000000000000

4080000000000000 L=42 NB=0.50000000000000000000000000000000000000000000

4080000000000000 L=43 NB=0.500000000000000000000000000000000000000000000

4080000000000000 L=44 NB=0.5000000000000000000000000000000000000000000000

4080000000000000 L=45 NB=0.50000000000000000000000000000000000000000000000

4080000000000000 L=46 NB=0.500000000000000000000000000000000000000000000000

4080000000000000 L=47 NB=0.5000000000000000000000000000000000000000000000000

4080000000000000 L=48 NB=0.50000000000000000000000000000000000000000000000000

4080000000000000 L=49 NB=0.500000000000000000000000000000000000000000000000000

4080000000000000 L=50 NB=0.5000000000000000000000000000000000000000000000000000


I'll report it. I hope this is accepted as abnormal. It's a hard battle at times.

Ask a Question
Discussion stats
  • 37 replies
  • 11 in conversation