Obsidian | Level 7

## SAS decimal points unexpected result

Dear Support,

I have a very simple program which used a number to divide group, but the result is unexpected. I cannot find the reason for this. Could you please help me with this? Please see the program below:

data t1;

input id a b;

cards;

1 56 50.4

2 25 22.5

3 55 49.4

;

run;

data t2;

set t1;

c=((a-b)*100/a);

group=0;

if 0<=c=10 then group=1;

if c>10 then group=0;

run;

For id 1 and 2, c has value of 10, so group should equal to 1, however, group has 0 and 1.

Any help is appreciated. thanks.

Xiumei

1 ACCEPTED SOLUTION

Accepted Solutions
Meteorite | Level 14

## Re: SAS decimal points unexpected result

You obviously have an error in your program. The statement

``````    if 0<=c=10 then group=1;
``````

resolves to

``  if 0<=c and c=10;``

So I assume that you meant

``  if 0<=c<=10 then group=1;``

The problem you have, apart from that, is that SAS floating points are base 2, not base 10. This means that a decimal which is not a (negative) power of 2 is not represented exactly. So, for ID = 1 you have 50.4, which is not exactly representable in base 2. And, obviously, while the C value displays as 10, it is not exactly 10. If you subset your output data with "where c=10", you will see that your first observation is not included.

You can use ROUND to get around this problem, e.g.:

``c=round((a-b)*100/a,0.0001);``
5 REPLIES 5
Super User

## Re: SAS decimal points unexpected result

did you intend

if 0<= c <=10 then group=1;

if 0<=c=10 then group=1;

in the latter if c is not equal to 10 then the c=10 bit is false and group is not set to 1

Obsidian | Level 7

## Re: SAS decimal points unexpected result

Thanks for your reply, but  "if 0<= c <=10 then group=1" is doing the same thing, doesn't work.

Super User

## Re: SAS decimal points unexpected result

Your IF statment is likely missing a < sign.

``````    if 0<=c=10 then group=1;

if c>10 then group=0;``````

Should likely be:

``````    if 0 <= c <= 10 then group=1;
else if c > 10 then group=0; * not needed since it was set already to 0;``````

You also may want to round the number to avoid issues.

This may help:

``````data t1;
input id a b;
cards;
1 56 50.4
2 25 22.5
3 55 49.4
;

run;

data t2;

set t1;

c=((a-b)*100)/a;
d = round(c, 0.001);

group=0;

if 0 <= c <= 10 then group=1;
else if c > 10 then group=0; * not needed since it was set already to 0;

if 0 <= d <= 10 then groupD=1;
else if d > 10 then groupD=0; * not needed since it was set already to 0;
format c d 8.3;
run;``````

@yangx wrote:

Dear Support,

I have a very simple program which used a number to divide group, but the result is unexpected. I cannot find the reason for this. Could you please help me with this? Please see the program below:

data t1;

input id a b;

cards;

1 56 50.4

2 25 22.5

3 55 49.4

;

run;

data t2;

set t1;

c=((a-b)*100/a);

group=0;

if 0<=c=10 then group=1;

if c>10 then group=0;

run;

For id 1 and 2, c has value of 10, so group should equal to 1, however, group has 0 and 1.

Any help is appreciated. thanks.

Xiumei

Meteorite | Level 14

## Re: SAS decimal points unexpected result

You obviously have an error in your program. The statement

``````    if 0<=c=10 then group=1;
``````

resolves to

``  if 0<=c and c=10;``

So I assume that you meant

``  if 0<=c<=10 then group=1;``

The problem you have, apart from that, is that SAS floating points are base 2, not base 10. This means that a decimal which is not a (negative) power of 2 is not represented exactly. So, for ID = 1 you have 50.4, which is not exactly representable in base 2. And, obviously, while the C value displays as 10, it is not exactly 10. If you subset your output data with "where c=10", you will see that your first observation is not included.

You can use ROUND to get around this problem, e.g.:

``c=round((a-b)*100/a,0.0001);``
Obsidian | Level 7

## Re: SAS decimal points unexpected result

Thank you for your reply and explanation. I tried to use round function and it works. So based on your explanation, whenever decimal number is produced, we should use round function, otherwise, the result might be unexpected.

yangx

Discussion stats
• 5 replies
• 645 views
• 0 likes
• 4 in conversation