I am computing the daily change/return of a series. In many cases, the value should be 0 because the value does not change. However, instead of 0, SAS produces extremely small values such as -3.76158E-37. What is going on? I read somewhere that sometimes the computer does that but cannot remember why/how. How do I address this issue apart from rounding the number such as
change = round (value/value_lag1, 0.0000000001)
Not sure if it helps but the time series variable has an informat 12. and format best12.
toin the direction ofMore (Definitions, Synonyms, Translation)
The issue is called "precision" and all computers have limits as to how many decimal can be stored in binary form. Depending on how many bits a numeric value can be used to store values determines how many digits are accurately represented. The more calculations involved the more likely that you start loosing small amounts at the limits of storage and can generate internal round-off errors such as you see. With SAS the typical limit is 15 or 16 significant digits depending on operating system.
All irrational or repeating decimals have such an issue and never fit exactly. 1/3 is 0.3333333333333333 (until you get tired of typing 3 and it still goes on).
So if that is your need then controlling the result of your calculations by rounding, truncating or other approach may be required. You might find the FUZZ function of use as it returns the nearest integer if the value is within 1E-12 of an integer.
change = fuzz (value/value_lag1);
The issue is called "precision" and all computers have limits as to how many decimal can be stored in binary form. Depending on how many bits a numeric value can be used to store values determines how many digits are accurately represented. The more calculations involved the more likely that you start loosing small amounts at the limits of storage and can generate internal round-off errors such as you see. With SAS the typical limit is 15 or 16 significant digits depending on operating system.
All irrational or repeating decimals have such an issue and never fit exactly. 1/3 is 0.3333333333333333 (until you get tired of typing 3 and it still goes on).
So if that is your need then controlling the result of your calculations by rounding, truncating or other approach may be required. You might find the FUZZ function of use as it returns the nearest integer if the value is within 1E-12 of an integer.
change = fuzz (value/value_lag1);
Sas numeric variables are saved, even integers, as exponential.
You are computing daily change/return. Usually you need 2 decimal digits.
For reporting use a format like 12.2.
For checking is the value zero round or use the int() function.
Hi @somebody,
At first glance this looks like yet another rounding issue related to precision and numeric representation errors which have been discussed in a number of threads. However, your example is somewhat special in two ways:
If the value in the series really doesn't change, the standard formulas for change or return should not produce those tiny differences. So I suspect that the input values already are affected by rounding errors and only the formatted display ("best12.") makes them appear equal.
@somebody wrote:
I am computing the daily change/return of a series. In many cases, the value should be 0 because the value does not change.
It would be interesting to see an example of two (seemingly) equal values of your time series, the formula (and the operating system) used to compute the change or return and the resulting tiny difference.
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.