BookmarkSubscribeRSS Feed
Anto180788
Calcite | Level 5

Good Afternoon,

 

I have a problem related to display the correct value.

 

I need to show value 999999999999999.99 in a numeric variable called E_IMP_AMOUNT.

The code is following:

 

data test;

set tab_input;

if strip(IMPAIRMENT_AMOUNT_V_120_CD)=" " then E_IMPAIRMENT_AMNT=999999999999999.99

else E_IMPAIRMENT_AMNT= input(strip(IMPAIRMENT_AMOUNT_V_120_CD),18.2)M

format E_IMPAIRMENT_AMNT 18.2;

run;

 

When I run the script, the value in the E_IMPAIRMENT_AMNT column is 1000000000000000.00.

 

I red somewhere in this forum it is a SAS'limit numer storage fixed to 15.

 

Have you any idea?

 

Thank you

 

11 REPLIES 11
PaigeMiller
Diamond | Level 26

SAS cannot display more than about 15 digits correctly.

 

You can get increased precision use SAS DS2. In this case, its hard to know if that is worth the effort or not, as we don't know why you want to display exactly 999999999999999.99. Could you explain?

--
Paige Miller
Anto180788
Calcite | Level 5

@PaigeMiller wrote:

SAS cannot display more than about 15 digits correctly.

 

You can get increased precision use SAS DS2. In this case, its hard to know if that is worth the effort or not, as we don't know why you want to display exactly 999999999999999.99. Could you explain?


HI @PaigeMiller

thank you very much for your answer!

I need that value as default value. So i have to display that.

 

Regarding SAS DS2, can you tell me what are step to increase the precision ?

 

Thank you very much

 

Antonio

 

Tom
Super User Tom
Super User

What do you mean by "default value"?

 

What does the variable represent? What are the range of values?   How many significant digits are there in the number? 

 

Will you be doing ARITHMETIC with this value?  Will you need to find the MEAN value?  Of find a change in value?  

PaigeMiller
Diamond | Level 26

@Anto180788 wrote:

@PaigeMiller wrote:

SAS cannot display more than about 15 digits correctly.

 

You can get increased precision use SAS DS2. In this case, its hard to know if that is worth the effort or not, as we don't know why you want to display exactly 999999999999999.99. Could you explain?


HI @PaigeMiller

thank you very much for your answer!

I need that value as default value. So i have to display that.

 

Regarding SAS DS2, can you tell me what are step to increase the precision ?


I gave a link to the DS2 manual. Beyond that, I cannot help.

 

I don't know why you have to display 1 quadrillion, minus 0.01, which is 999999999999999.99. Seems pointless to me. Explain why it has to be displayed as 999999999999999.99. Explain why 1 quadrillion does not work for you.

--
Paige Miller
Anto180788
Calcite | Level 5
My boss said me to put this value. So it is just a conventional value.
Tom
Super User Tom
Super User

@Anto180788 wrote:
My boss said me to put this value. So it is just a conventional value.

So explain to your boss that it is impossible to store such a value exactly in a SAS numeric variable.

 

Ask why you cannot just leave the value MISSING.

Or use some other arbitrary large value, such as an INTEGER, that can be precisely stored.

Anto180788
Calcite | Level 5
I already said that TOM.
Tomorrow will discuss this problem.
In fact it was very absurd to put this value. We have to check if there is regulatory requirement about the length of thi value.
Quentin
Super User

From this:

if strip(IMPAIRMENT_AMOUNT_V_120_CD)=" " then E_IMPAIRMENT_AMNT=999999999999999.99 ;
else E_IMPAIRMENT_AMNT= input(strip(IMPAIRMENT_AMOUNT_V_120_CD),18.2) ;

it looks like you're using 999999999999999.99 as a missing value code.  This is a bad idea in SAS, because it will look to SAS like a number, not a missing value.  In some other languages (like SPSS), you can tell the language that a 9 is a missing value.

 

In SAS, you're better off using special missing values to store missing values, assuming you have different types of missings you want to distinguish.  So you could code this as:

if IMPAIRMENT_AMOUNT_V_120_CD=" " then E_IMPAIRMENT_AMNT=.M ;
else E_IMPAIRMENT_AMNT= input(IMPAIRMENT_AMOUNT_V_120_CD,18.2) ;

Only heartache and confusion will come from coding missing values as 9 or 99 or 999999999 etc. 

 

For more on special missing values, the first UG paper I ever wrote was on the topic. https://www.lexjansen.com/nesug/nesug01/ps/ps8009.pdf

 

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Anto180788
Calcite | Level 5
Hi Quentin,

I put this value in place of missing value.
I will think to use these special missing values as you said.

Thank you
ballardw
Super User

For those that absolutely must show a poorly designed serious of characters for a value that actually is not present then a custom format will display any such.

 

proc format;
value mymissing
. = '999999999999999.99'
other = [best16.]
;
run;

data have;
 input x;
datalines;
.
123456
123456789
;

title 'Default format';
proc print data=have;
run;
title 'Use custom format';
proc print data=have;
   format x mymissing.;
run;

title;

Then the missing value never impacts calculations like a large actual numeric value would and the Format allows the "boss" to see what he expects/wants.

 

 

Tom
Super User Tom
Super User

Also why are you implying a decimal place before the last digits?  Do the strings intentionally not include the period character to indicate the location of the decimal place?

 

That what the .2 in the informat specification 18.2 means. 

 

Read in 18 characters and if there is not explicit decimal point then divide the resulting value by 10**2.

Note also that the INPUT() function does not care if the width of the informat is longer than the string being read. So just use the maximum width that the informat allows.  And there is no need to remove the spaces if the variable is not longer than 32 bytes.  And if it is you only need to remove the leading spaces.

E_IMPAIRMENT_AMNT=input(left(IMPAIRMENT_AMOUNT_V_120_CD),32.);

If you want to test anything you should test that the string is not longer than 32 bytes.

if length(left(IMPAIRMENT_AMOUNT_V_120_CD))<= 32 then
  E_IMPAIRMENT_AMNT=input(left(IMPAIRMENT_AMOUNT_V_120_CD),32.)
;

 

And using STRIP here makes no sense either:

if strip(IMPAIRMENT_AMOUNT_V_120_CD)=" "

SAS will treat a string of 100 spaces and one with only one space as being equal since it ignores the trailing spaces.

 

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 789 views
  • 6 likes
  • 5 in conversation