考虑以下程序和输出:
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,Windows 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
这种行为至少对我来说是意料之外的,并且似乎没有记录在help page上。它同意我发现here宽度为64的文档 - 标准双精度 - 但我不明白为什么它会在宽度59处翻转。
答案 0 :(得分:1)
我得不到相同的结果 - 我的开关是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。 format将实数二进制数转换为定点整数,然后将其写为十六进制字符。它还以二进制补码表示法写入负数,右对齐数字。如果w是16,HEXw。以十六进制形式显示浮点值。
Binary正在做同样的事情,在我的机器上它恰好发生在HEX也会做出改变 - 在15x4 = 60。 HEX.
显示相同的信息 - 下面注明; hex4.
和hex8.
显示的结果与hex16.
不同。
要清楚,binary64.
显示的值是正确的,而不是任何类型的截断(尽管61-63,在您的示例59-60中,左截断)。
我确实找到了一个SAS usage note,虽然它根据我们的测试明显过时了:
从SAS®V7开始,BINARYw。格式被改为与HEXw更加一致。格式。当HEXw。 format使用16的宽度(对应于8个字节的数据),它生成浮点值的十六进制表示。 BINARYw。格式已更改,因此宽度为57-64会生成浮点值的二进制表示,因为57-64的宽度对应于8个字节的数据。
它还包含如何获得整数的一致结果的建议,这可能是有用的。
BIN_64 = PUT(PUT(VALUE,S370FIB8),$ BINARY64);
S370FIB8.
是一个format,它将数字转换为IBM Mainframe格式的固定整数二进制表示形式。 (即,它以Big-Endian格式写入整数,这不是您在Intel机器上获得的。)