BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Esreg
Calcite | Level 5

For numeric variables in SAS, for numbers greater than 16th numeric value it shows different values - SAS can only read up to 16 decimal digits and the rest of the digits will be generated randomly. Is there a way to change the default length of the readable numeric digits?

I would like to retain the variable as numeric not character, and I would like to extend the number of digits beyond 16.

 

data demo1;
input CRDNO ;
FORMAT CRDNO BEST21.;
CARDS;
123456789123456791234
111111111111111111111111

222222222222222222222
RUN;
proc print;

run;

 

SAS output will show only up to 16 numeric value but greater than 16th numeric value it shows different values. And I believe the last few digits of the numbers are random.

Obs

CRDNO

1

123456789123456794624

2

111111111111111114752

3

222222222222222229504

1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

Hello @Esreg and welcome to the SAS Support Communities!

 

Numeric variables in SAS datasets have a length of up to 8 bytes. Even the BIGINT type mentioned by Rick_SAS is limited to 8 bytes. The set of positive 21-digit decimal integers (i.e. from 1E20 through 1E21-1) comprises 9E20 numbers. Eight bytes (= 64 bit), however, can only store up to 2**64=1.84...E19 distinct values, regardless of the hardware or software platform used. So it is impossible to represent all those 9E20 numbers with an 8-byte variable of any sort. Trying to store such a number in a numeric variable typically leads to a rounded or truncated internal binary representation, which results in decimal numbers ending in seemingly "random" digits, as you have noticed.

 

If you really need to perform certain calculations with those long integers, there are workarounds available:

  • Split the CRDNO values into two shorter digit strings (of less than 16 digits), store these in two numeric variables and write code to perform the calculations using the two parts of the numbers.
  • Store the CRDNO values in a character variable and perform the calculations on a digit-by-digit basis in SAS (examples: Mod function with big number, base conversion) or by calling external modules written in other languages.

View solution in original post

5 REPLIES 5
Rick_SAS
SAS Super FREQ

In the DATA step, people often read big integers (such as SSN numbers or bank accounts) as character values. In general, if the number is an identifier and you do not intend to perform arithmetic on it, then read it as a character variable. 

 

The DS2 procedure supports the BIGINT (Int64 = 64-bit integers), as does the CAS server. See

https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/ds2pg/n0v130wmh3hmuzn1t7y5y4pgxa69.htm

and

 https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/ds2pg/p0x19g0gas4lvtn1o48uba5wq1vd.htm

:   

If you search the internet for "SAS BIGINT type" you can find additional information and discussion.

 

 

FreelanceReinh
Jade | Level 19

Hello @Esreg and welcome to the SAS Support Communities!

 

Numeric variables in SAS datasets have a length of up to 8 bytes. Even the BIGINT type mentioned by Rick_SAS is limited to 8 bytes. The set of positive 21-digit decimal integers (i.e. from 1E20 through 1E21-1) comprises 9E20 numbers. Eight bytes (= 64 bit), however, can only store up to 2**64=1.84...E19 distinct values, regardless of the hardware or software platform used. So it is impossible to represent all those 9E20 numbers with an 8-byte variable of any sort. Trying to store such a number in a numeric variable typically leads to a rounded or truncated internal binary representation, which results in decimal numbers ending in seemingly "random" digits, as you have noticed.

 

If you really need to perform certain calculations with those long integers, there are workarounds available:

  • Split the CRDNO values into two shorter digit strings (of less than 16 digits), store these in two numeric variables and write code to perform the calculations using the two parts of the numbers.
  • Store the CRDNO values in a character variable and perform the calculations on a digit-by-digit basis in SAS (examples: Mod function with big number, base conversion) or by calling external modules written in other languages.

SASKiwi
PROC Star

Looks like you are reading credit card numbers. Since you won't be doing calculations on them there is absolutely no reason not to read them as character. I deal with credit card numbers all the time and we always define them as 16 characters. 

Tom
Super User Tom
Super User

You can ask SAS to show you the largest integer it can store as a number before it you start seeing collisions of two or more integers to the same number.

1757  data _null_;
1758    big=constant('exactint');
1759    put big :comma24.;
1760  run;

9,007,199,254,740,992

Any numbers longer than that you should store as character strings instead.

data demo1;
  input @1 String $21. @1 number ;
  put '_INFILE_: ' _infile_ :21.
    / 'STRING  : ' string 
    / 'NUMBER  : ' number 21. 
    / 
  ;
CARDS;
123456789012345678901
111111111111111111111
222222222222222222222
;
_INFILE_: 123456789012345678901
STRING  : 123456789012345678901
NUMBER  : 123456789012345683968

_INFILE_: 111111111111111111111
STRING  : 111111111111111111111
NUMBER  : 111111111111111114752

_INFILE_: 222222222222222222222
STRING  : 222222222222222222222
NUMBER  : 222222222222222229504

If you are reading your data from a text file, like a CSV file, then make sure to define the variable has character when you read it.

If you are getting these values from an external database then have the database cast the value as a string before sending it to SAS.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 5 replies
  • 1283 views
  • 4 likes
  • 6 in conversation