1

I am trying to convert a character variable containing a number into a numeric variable without losing decimal precision. Here is an example with output:

data _null_;
format res 20.17;
res = input("54.78566360473633",20.17);
put res;
run;

and the result:

54.78566360473630000

You can see that the number of digits in the result is correct, but the last non-zero digit does not match the final digit of the character variable. I've tried using formats with a larger and smaller number of digits (such as 18.15 or 15.13), and I've tried "forcing" the number of decimals with a format like f20.17, but none of this seems to be working.

I've tried looking through some documentation pages but nothing seems germane. I'm sure this is really basic stuff I'm missing here but, how can I get sas to faithfully read in all digits?

Rookatu
  • 1,487
  • 3
  • 21
  • 50
  • https://stackoverflow.com/questions/59743802/odd-behavior-with-sas-numeric-comparison-precision-issue – Tom Nov 12 '20 at 16:26
  • Hey @Tom, thanks for this link. So if I understand, SAS doesn't have any way to represent decimal formats (instead relying on floating point), and the character variables I have end up exhausting the precision threshold of the format? Even if I add more digits (e.g. 945) after the last digit in the character variable, the resultant output is the same. Am I understanding correctly? Thanks! – Rookatu Nov 12 '20 at 16:32
  • This is not the cause of your issue, but do not specify a decimal width on an INFORMAT unless you want SAS to divide strings without explicit decimal point by that power of 10. – Tom Nov 12 '20 at 16:33
  • SAS has two data types. Floating point numbers and fixed length character strings. Formats are just instructions for how to display the value. Informats are instructions for how to convert text into values. – Tom Nov 12 '20 at 16:34
  • Sorry, my question wasn't well formed. I guess what I'm asking is: is sas capable of storing a value such as 54.78566360473633 in a numeric variable, and if so how can I ensure that this value is being stored i.e. what format should I specify to see the full and accurate decimal expansion? Also, I've altered the input format to be 20. (I had done this originally but ended up playing around with the decimal length when I couldn't get the expected output). – Rookatu Nov 12 '20 at 16:38
  • 1
    Decimal numbers cannot be stored exactly using binary numbers. Your last decimal place is beyond the limits of the precision with which decimal values can be stored as binary numbers using the 8 byte floating point representation SAS uses. – Tom Nov 12 '20 at 16:47

1 Answers1

2

SAS has two data types. Floating point numbers and fixed length character strings. Formats are just instructions for how to display the value. Informats are instructions for how to convert text into values. Neither the FORMAT attached to a variable or the INFORMAT used to create the values in the variable have any impact on how the number is stored.

If you want to use decimal arithmetic then store your values as integers and keep track of the exponent in a separate variable. But even then you will be limited in the precision you can store based on the size of the mantissa used in the floating point representation used by your version of SAS. You can see the largest contiguous integer that SAS can store exactly using the EXACTINT option of the CONSTANT() function.

Tom
  • 47,574
  • 2
  • 16
  • 29