Hi there. 🤔
I have an issue with decimals in numeric fields. I read somewhere SAS can be pretty accurate up to 15 - 16 decimals. Say let's say I have a z19:16 formatted numeric field (I need to format it (I think!) to get more than 10 decimals which I think is the standard if the variable is just defined as numeric) that contains: 12.775. I need to send this to a mainframe to which we only can send integers. So to make the mainframe understand it is 12.775, I need to send 12775 and the no. of decimal positions as a separate number, i.e. 3. Another example would be 12.6802 where I have to send 126802 and 4 to "tell" the mainframe to divide by 10.000. So my problem is this: I am not so much into HEX codes and what is going on regarding the internal form SAS operates with with huge number - either before or after the decimal point. The solutions I found on the net use SUBST and SCAN function that normally would do good for text variables but ALSO it seems for numbers up to 10 digits before or after the decimal point (I guess that relates to the entire HEX issue). Yes, I do sound like somebody who need to train to understand this but I have a deadline and need to solve this quick.
So in short .. the code I'll send after this text works for values up to 10 digits. If I have more the result is unpredictable. I need to code this different than what I did below. I need some code that can give me 12 for 77,123456789012, 3 for 66,378, 14 for 95,12345678901234. How do code that people?
What I did to get the right the answer ... (that only works up to 10 decimals). I build a table with some values and then use two methods I found on the internet to determine the number of decimals:
Run the code if you want and then read what I wrote after it.
/* Create a little test data. */
data decimal_play;
format pi_1 pi_2 pi_3 pi_4 pi_5 Z20.17 ;
pi_1 = 3.141592650000000;
pi_2 = 3.141592653000000;
pi_3 = 3.141592653500000;
pi_4 = 3.141592653580000;
pi_5 = 3.141592653589793;
run;
/* Method 1 */
data Method_1 (keep = dec_pi_1 dec_pi_2 dec_pi_3 dec_pi_4 dec_pi_5);;
set decimal_play;
dec_pi_1 = lengthn(scan(cat(pi_1),2,'.'));
dec_pi_2 = lengthn(scan(cat(pi_2),2,'.'));
dec_pi_3 = lengthn(scan(cat(pi_3),2,'.'));
dec_pi_4 = lengthn(scan(cat(pi_4),2,'.'));
dec_pi_5 = lengthn(scan(cat(pi_5),2,'.'));
output;
run;
/* Method 2 */
data Method_2 (keep = dec_pi_1 dec_pi_2 dec_pi_3 dec_pi_4 dec_pi_5);
set decimal_play;
first = substr(pi_1, 1, index(pi_1, '.') - 1); second = left(substr(pi_1, index(pi_1, '.') + 1)); dec_pi_1 = LENGTH(second);
first = substr(pi_2, 1, index(pi_2, '.') - 1); second = left(substr(pi_2, index(pi_2, '.') + 1)); dec_pi_2 = LENGTH(second);
first = substr(pi_3, 1, index(pi_3, '.') - 1); second = left(substr(pi_3, index(pi_3, '.') + 1)); dec_pi_3 = LENGTH(second);
first = substr(pi_4, 1, index(pi_4, '.') - 1); second = left(substr(pi_4, index(pi_4, '.') + 1)); dec_pi_4 = LENGTH(second);
first = substr(pi_5, 1, index(pi_5, '.') - 1); second = left(substr(pi_5, index(pi_5, '.') + 1)); dec_pi_5 = LENGTH(second);
run;
So how should I code this nicely? Code that reads a number, gives me the number as an integer (max 18 long, i.e.: 2 before the decimal point and 16 after) and the number of decimals is a separate variable.
3.141592650000000 as 314159265 & 8
3.141592653000000 as 3141592653 & 9
3.141592653500000 as 31415926535 & 10
3.141592653580000 as 314159265358 & 11
3.141592653589793 as 3141592653589793 & 15
Best regards,
Menno 🙈
... View more