Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Home
- /
- Programming
- /
- Programming
- /
- SAS decimal points unexpected result

Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

🔒 This topic is **solved** and **locked**.
Need further help from the community? Please
sign in and ask a **new** question.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 02-28-2019 04:32 PM
(650 views)

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

did you intend

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

instead of

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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);`

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

**Don't miss out on SAS Innovate - Register now for the FREE Livestream!**

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

How to Concatenate Values

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.