2009-05-07 9 views
2

Следующий код SAS:Почему в 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 до 1e25. В следующей программе:


%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 

ответ

2

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

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

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

Update 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; 

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

+0

Я не ограничиваю длину своих цифр; они являются «длиной 8» (64 бит). –

+0

Я отредактировал вопрос, чтобы дать значения для других степеней 10. –