Почему в SAS числовой литерал в научной записи дает другое число, чем число, записанное явно? - PullRequest
2 голосов
/ 07 мая 2009

следующий код SAS:

data _null_;
  format t u best32.;
  t = 10000000000000000000000000;
  u = 1e25;
  put t u;
  if t ne u then put 'diff';
run;

на моей машине с Windows печатает:

10000000000000000905969664 9999999999999998758486016
diff

Хотя я понимаю, что доверять нужно только первым 15-16 цифрам, почему они вообще дают разные базовые числа? Как SAS вычисляет 1e25?

Редактировать: меня попросили дать выход для других степеней от 10 до 1е25. Следующая программа:


%macro doit;
data _null_;
  format t u best32.;
%let t=1;
%do i=1 %to 25;
  %let t=&t.0;
  t = &t;
  u = 1e&i;
  put t u;
%end;
run;
%mend;
%doit;

дает следующий вывод:


10 10
100 100
1000 1000
10000 10000
100000 100000
1000000 1000000
10000000 10000000
100000000 100000000
1000000000 1000000000
10000000000 10000000000
100000000000 100000000000
1000000000000 1000000000000
10000000000000 10000000000000
100000000000000 100000000000000
1000000000000000 1000000000000000
10000000000000000 10000000000000000
100000000000000000 100000000000000000
1000000000000000000 1000000000000000000
10000000000000000000 10000000000000000000
100000000000000000000 100000000000000000000
1000000000000000000000 1000000000000000000000
10000000000000000000000 10000000000000000000000
99999999999999991611392 99999999999999991611392
999999999999999983222784 999999999999999983222784
10000000000000000905969664 9999999999999998758486016

1 Ответ

2 голосов
/ 07 мая 2009

Похоже, что на самом деле он вычисляет 1 * 10 * 10 ... * 10, и ошибки появляются, как только вы выходите за рамки значительного числа битов для базового типа с плавающей запятой.

Но я не верю, что это произойдет для типа float / double типа IEE754, поскольку он вполне может представлять 1x10 полный диапазон без потери точности.

Одна из возможностей заключается в том, что проблема, с которой вы сталкиваетесь, связана со способностью сохранять поплавки с меньшей точностью, чем разрешено (что может привести к искажению вычисления 1e25) - см. Объяснение http://www.uc.edu/sashtml/lrcon/z0695157.htm#z0695187.

Обновление 1:

Хорошо, исходя из вашего комментария, вы не ограничиваете длину. Что дает следующий код?

t = 10;
u = 1e1;
put t u;
t = 100;
u = 1e2;
put t u;
t = 1000;
u = 1e3;
put t u;
: : :
t = 10000000000000000000000000;
u = 1e25;
put t u;

Основываясь на этом выводе, мы, вероятно, можем сделать вывод, что происходит под одеялом.

...