Hi SASians,
I have noticed something weird today while using long int in SAS dataset, it is getting printed slightly different value
even after using format . I believed this is something related to scientific notation E to real value goes wrong in PDV ..
or am I missing something here ??
Any suggestion and why it is like that ?
data dummy;
infile cards;
input a 30.;
format a 30.;
cards;
231512182813021801
run;
getting 231512182813021792 , expected value 231512182813021801.
Regards,
SAR
Hi @arunrami,
Here are the details of what SAS did to your numeric literal 231512182813021801 (assuming a Windows or Unix operating system):
1100110110011111110001101010001001101111101101011001101001Note that it has 58 binary digits.
1100110110011111110001101010001001101111101101011001100000The last 58−53=5 original binary digits, 01001, started with 0 and hence have been rounded down. (This has the same effect as subtracting 01001, i.e. 9 in the decimal system, from the original number.)
231512182813021792
The 53 bits mentioned in item 2 are the so called "implied bit" plus the 52 mantissa bits which SAS stores internally besides the 1+11 bits for the sign and exponent, respectively (see Numerical Accuracy in SAS Software [linked by yabwon already] for more details).
To avoid the loss of precision, you should store integers of this size in character variables, as Kurt Bremser has recommended. Using PROC DS2 or PROC FedSQL you can still handle them (up to certain limits, see BIGINT data type) as numeric values: see the old thread Convert large number for an example. Certain calculations can even be done digit by digit in a DATA step (example: Mod function with big number).
SAS does not have the datatype longint (except in some special circumstances).
SAS stores all numbers in 8-byte real, which means that the maximum precision is about 15 decimal digits, and that causes the effect you see here.
For statistical analysis, such precision is not needed, and if you have something that is not in fact a number, but some kind of code (eg telephone numbers or SSN), you are better off storing it as character.
@arunrami wrote:
Hi SASians,
I have noticed something weird today while using long int in SAS dataset, it is getting printed slightly different value
even after using format . I believed this is something related to scientific notation E to real value goes wrong in PDV ..
or am I missing something here ??
Any suggestion and why it is like that ?
data dummy;
infile cards;
input a 30.;
format a 30.;
cards;
231512182813021801
run;
getting 231512182813021792 , expected value 231512182813021801.
Regards,
SAR
Thanks for the reponse
, but I really want it as a number and also am fetching from database hence it would be better if I can store and see the result as it is..
and converting the datatype to character also doesn't seem to be solving the problem..find here
data fil;
set dummy;
b = put(a,20.);
where a = 231512182813021801 ;
run;
is there any other way to read and print these kind of as it is ?
@arunrami wrote:
Thanks for the reponse
, but I really want it as a number and also am fetching from database hence it would be better if I can store and see the result as it is..
and converting the datatype to character also doesn't seem to be solving the problem..find here
data fil;
set dummy;
b = put(a,20.);
where a = 231512182813021801 ;
run;
is there any other way to read and print these kind of as it is ?
Well, a has already lost precision, so converting it within SAS is useless. You need to import it as character in the first place.
And, as I already said, if it IS a number, such precision makes no sense in a statistics environment. It's another thing if you need the GDP of the USA down to cents, but we're not doing the national accounting here 😉
Hi,
The 9,007,199,254,740,992 is max what SAS can store in 8 bytes on WIN or Linux. Please see the doc here:
for details (section "Maximum Integer Size").
All the best
Bart
Hi @arunrami,
Here are the details of what SAS did to your numeric literal 231512182813021801 (assuming a Windows or Unix operating system):
1100110110011111110001101010001001101111101101011001101001Note that it has 58 binary digits.
1100110110011111110001101010001001101111101101011001100000The last 58−53=5 original binary digits, 01001, started with 0 and hence have been rounded down. (This has the same effect as subtracting 01001, i.e. 9 in the decimal system, from the original number.)
231512182813021792
The 53 bits mentioned in item 2 are the so called "implied bit" plus the 52 mantissa bits which SAS stores internally besides the 1+11 bits for the sign and exponent, respectively (see Numerical Accuracy in SAS Software [linked by yabwon already] for more details).
To avoid the loss of precision, you should store integers of this size in character variables, as Kurt Bremser has recommended. Using PROC DS2 or PROC FedSQL you can still handle them (up to certain limits, see BIGINT data type) as numeric values: see the old thread Convert large number for an example. Certain calculations can even be done digit by digit in a DATA step (example: Mod function with big number).
Thanks @FreelanceReinh , @FreelanceReinh and @yabwon .
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!
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.