考虑以下程序和输出:
data _null_;
input a;
length b $64;
do i = 1 to 64;
fmtname = cats('binary',i);
b = cats(putn(a,fmtname));
put i= b=;
end;
cards;
1
;
run;
输出(SAS 9.1.3,视窗 7 x64):
i=1 b=1
i=2 b=01
i=3 b=001
i=4 b=0001
i=5 b=00001
/*Skipped a few very similar lines*/
i=58 b=0000000000000000000000000000000000000000000000000000000001
i=59 b=11111110000000000000000000000000000000000000000000000000000
i=60 b=111111110000000000000000000000000000000000000000000000000000
i=61 b=1111111110000000000000000000000000000000000000000000000000000
i=62 b=11111111110000000000000000000000000000000000000000000000000000
i=63 b=011111111110000000000000000000000000000000000000000000000000000
i=64 b=0011111111110000000000000000000000000000000000000000000000000000
Linux x64 上 SAS 9.4 输出的最后几行:
i=60 b=000000000000000000000000000000000000000000000000000000000001
i=61 b=1111111110000000000000000000000000000000000000000000000000000
i=62 b=11111111110000000000000000000000000000000000000000000000000000
i=63 b=011111111110000000000000000000000000000000000000000000000000000
i=64 b=0011111111110000000000000000000000000000000000000000000000000000
至少对我来说,这种行为是相当出乎意料的,并且似乎没有记录在帮助页面上。它与我在这里找到的宽度为 64 的文档一致 - 标准双精度 - 但我不明白为什么它在宽度 59 处翻转。
我没有得到完全相同的结果 - 我的开关在 61 - 但我相信答案是相同的。
直到某个点 - 58,60,在那里的某个地方 - SAS正在向您展示数字的定点整数表示形式。 用小数测试,如下所示:
data _null_;
a=3.14159265358979323846264338327950288419716939937510582;
length b $64;
put a= hex4.;
put a= hex8.;
put a= hex16.;
do i = 1 to 64;
fmtname = cats('binary',i);
b = cats(putn(a,fmtname));
put i= b=;
end;
run;
你会得到一个令人惊讶的结果 - 你看到大部分行的000...0011
,直到60行。 文档没有明确提到这一点,但它确实在示例中显示了它(123.45 和 123 在 binary8.
中是相同的)。
然后从 61 开始,或者我猜是 59,你会看到 SAS 内部存储它时数字的实际表示形式(或者,可以说,英特尔内部存储它的方式)。
二进制文档不能很好地解释这一点,但HEX.
文档确实在提示中非常清楚地解释了它:
如果 w<16,则 HEXw. 格式将实二进制数转换为定点整数,然后再将其写入十六进制字符。它还以二进制的补码表示法写入负数,并右对齐数字。如果 w 为 16,则十六进制。以十六进制形式显示浮点值。
二进制也在做同样的事情,在我的机器上,它发生在 HEX 也会进行更改的地方 - 在 15x4=60 处。 HEX.
显示相同的内容 - 下面的通知; hex4.
和hex8.
显示的结果与hex16.
不同。
需要明确的是,binary64.
处显示的值是正确的,而不是任何类型的截断(尽管 61-63 和示例中的 59-60 被左截断)。
我确实找到了有关此的SAS使用说明,尽管根据我们的测试,它显然已经过时了:
从 SAS® 版本 7 开始,BINARYw. 格式已更改为与 HEXw. 格式更一致。当十六进制。格式使用宽度为 16,(对应于 8 个字节的数据),它生成浮点值的十六进制表示形式。比纳里乌。格式已更改,以便宽度 57-64 生成浮点值的二进制表示形式,因为宽度 57-64 对应于 8 个字节的数据。
它还包含有关如何获得整数的一致结果的建议,这些建议可能会有用。
BIN_64=PUT(PUT(VALUE,S370FIB8.),$BINARY 64.);
S370FIB8.
是一种将数字转换为其固定整数二进制表示形式的格式,采用 IBM 大型机格式。 (即,它以大端格式写入整数,这不是您在英特尔机器上得到的。