为什么在 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
The following SAS code:
data _null_;
format t u best32.;
t = 10000000000000000000000000;
u = 1e25;
put t u;
if t ne u then put 'diff';
run;
on my Windows machine prints out:
10000000000000000905969664 9999999999999998758486016
diff
While I understand that only the first 15-16 digits are to be trusted, why do they give different underlying numbers at all? How is SAS computing 1e25?
Edit: I've been asked to give the output for other powers of 10 up to 1e25. The following program:
%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;
gives the following output:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来它实际上可能正在计算
1 * 10 * 10 ... * 10
并且一旦超出基础浮点类型的有效位数,错误就会悄悄出现。但我不认为 IEE754 类型的 float/double 会发生这种情况,因为它完全能够表示 1x10全范围 而不会损失精度。
一种可能性是,您遇到的问题与存储精度低于允许的浮点数的能力有关(这可能会搞砸 1e25 计算) - 请参阅 http://www.uc.edu/sashtml/lrcon/z0695157.htm#z0695187 获取解释。
更新 1:
好的,根据您的评论,您没有限制长度。 下面的代码给了你什么?
根据该输出,我们或许可以推断出幕后发生的事情。
It looks like it might actually be calculating
1 * 10 * 10 ... * 10
and the errors are creeping in as soon as you get beyond the significant number of bits for the underlying float type.But I don't believe that would happen for an IEE754 type float/double since it's quite able to represent 1x10full-range without loss of precision.
One possibility is that the problem you are having is related to the ability to store floats with less precision than allowed (which could possibly screw up a 1e25 calculation) - see http://www.uc.edu/sashtml/lrcon/z0695157.htm#z0695187 for an explanation.
Update 1:
Okay, so based on your comment, you're not restricting the length. What does the following code give you?
Based on that output, we can probably deduce what's going on under the covers.