Вы не сможете хранить такие большие целые числа точно в числовой форме SAS (64-разрядное двойное число).
С https://v8doc.sas.com/sashtml/win/numvar.htm
Значимые цифры и наибольшее целое по длине для переменных SAS в Windows
| Length | Largest Integer | Exponential
| (Bytes) | Represented Exactly | Notation
+---------+-----------------------+------------
| 3 | 8,192 | 2 ^ 13
| 4 | 2,097,152 | 2 ^ 21
| 5 | 536,870,912 | 2 ^ 29
| 6 | 137,438,953,472 | 2 ^ 37
| 7 | 35,184,372,088,832 | 2 ^ 45
| 8 | 9,007,199,254,740,992 | 2 ^ 53
Таким образом, хотя все 16-значные шестнадцатеричные значения в C
могут отчетливо вписываться в 64-разрядное целое число, не все такие могут отчетливо вписываться в числовые значения SAS (те, которые> 2**53
). Однако 64-битный дубль является стандартом IEEE и может работать с числами до ~ 10 ** 51, хотя и с некоторой потерей точности.
Этот код показывает, что два разных целочисленных назначения сохраняются как одно и то же числовое значение SAS, отличное от того, которое было присвоено.
data _null_;
x = 837886600861902976;
y = 837886600861902977;
put x= 20. / y= 20.;
if x=y then put 'Huh? Ooohhh.';
run;
---------------------
x=837886600861902848
y=837886600861902848
Huh? Ooohhh.
Один из подходов - разделить строку c-hex на «верхнюю» и «нижнюю» части и выполнить арифметику с их входами. Предостережение заключается в том, что произойдет потеря четкости / точности, когда фактическое шестнадцатеричное значение будет> 2 ** 53.
data _null_;
length H $30;
input H;
put h=;
if H =: '0x' then do;
HX = substr(H,3); * skip over 0x;
if (length (HX) > 15) then do;
HX_lower = substr(HX, length(HX)-14);
HX_upper = substr(HX, 1, length(HX)-15);
if length (HX_lower) > 15 then put 'ERROR: ' H= 'too big for two parts';
H_lower = input (HX_lower,hex15.);
H_upper = input (HX_upper,hex15.);
U = H_upper * 16**15;
L = H_lower;
put / H;
put HX_upper $16. ' ->' H_upper 20. ' ->' U 25.;
put HX_lower $16. ' ->' H_lower 20. ' ->' L 25.;
H_num = U + L;
end;
else do;
H_num = input (HX, hex15.);
end;
end;
else
put 'ERROR: ' H= 'is not c hex';
put H= H_num= comma30.;
datalines;
0x1
0x1b
0x1ba
0x1ba0
0x1ba0c
0x1ba0c5
0x1ba0c56
0x1ba0c56c
0x1ba0c56c9
0x1ba0c56c96
0x1ba0c56c966
0x1ba0c56c966e
0x1ba0c56c966ee
0x1ba0c56c966ee8
0x1ba0c56c966ee8b
0x1ba0c56c966ee8b0
0x1ba0c56c966ee8b00
0x1ba0c56c966ee8b000
0x1ba0c56c966ee8b0000
magic!
run;