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 |
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:
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.
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:
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.
If that is a (credit) card number, it must always be stored as character. You won't do calculations with it.
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.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.