DATA Step, Macro, Functions and more

Solved
Frequent Contributor
Posts: 138

Hi,

I have a dataset with two character variables (composed entirely of numbers). Each person will have a value for Char_var1 or Char_var2, but not both. I created a variable that basically combines the values of Char_var1 and Char_var2, so everyone will have a value for the combined variable. I wanted the combination variable to be numeric so I added a length statement:

data want;

length combined_var 3.;

set have;

if char_var1 ne " " then combined_var=char_var1;

else if char_var1=" " then combined_var=char_var2;

run;

The problem is that in the resulting dataset, the combined_var has added several digits to each value:

Char_var1     Char_var2     Combined_var

1.5                                            1.51493

6.3               6.32139

7.0                                            7.01493

I'm not sure where the digits came from--the source data has only one digit after the decimal point for Char_var1 and Char_var2. Any help is much appreciated.

Accepted Solutions
Solution
‎07-06-2015 03:44 PM
Super User
Posts: 6,751

Re: Numeric variable adding extra digits

The culprit here is the LENGTH statement.  SAS stores numerics in a converted format, storing the value (not the digits themselves).  Decimal fractions can't be stored exactly, and so should use a length of 8 (not 3) for maximum possible precision.

Even with that in mind, it's surprising that 1.5 and 7.0 can't be stored exactly.  Those are values that a length of 3 should be able to store with no trouble.  6.3 is another story.  Like trying to store 1/3 in a decimal system, there's no exact equivalent to 6.3 in a binary system.  But there are very short binary equivalents to 1.5 and 7.0 in binary (1.1, and 111).  Are those real-life examples, or are they typed in just to illustrate the issue?

All Replies
Community Manager
Posts: 3,424

Re: Numeric variable adding extra digits

Walternate,

Instead of allowing SAS to convert that character value into a number for you, you should probably convert it explicitly with an INPUT function.  For example:

combined_var=input(char_var1, 4.1); /* read in to first decimal precision */

More on this topic here:

http://blogs.sas.com/content/sgf/2015/05/01/converting-variable-types-do-i-use-put-or-input/

On the Fringe,

Chris

Solution
‎07-06-2015 03:44 PM
Super User
Posts: 6,751

Re: Numeric variable adding extra digits

The culprit here is the LENGTH statement.  SAS stores numerics in a converted format, storing the value (not the digits themselves).  Decimal fractions can't be stored exactly, and so should use a length of 8 (not 3) for maximum possible precision.

Even with that in mind, it's surprising that 1.5 and 7.0 can't be stored exactly.  Those are values that a length of 3 should be able to store with no trouble.  6.3 is another story.  Like trying to store 1/3 in a decimal system, there's no exact equivalent to 6.3 in a binary system.  But there are very short binary equivalents to 1.5 and 7.0 in binary (1.1, and 111).  Are those real-life examples, or are they typed in just to illustrate the issue?

Frequent Contributor
Posts: 138

Re: Numeric variable adding extra digits

You're right--I invented those examples, and now that I look at it more closely, the values ending in .0 or .5 were actually converted correctly.

Changing my length statement to 8. fixed the issue.

🔒 This topic is solved and locked.