在Bruce Eckel的'Thinking in C ++'中,有一个打印双值的程序 在二进制。 (第3章,第189页)
int main(int argc, char* argv[])
{
if(argc != 2)
{
cout << "Must provide a number" << endl;
exit(1);
}
double d = atof(argv[1]);
unsigned char* cp = reinterpret_cast<unsigned char*>(&d);
for(int i = sizeof(double); i > 0 ; i -= 2)
{
printBinary(cp[i-1]);
printBinary(cp[i]);
}
}
这里当i = 8时打印cp [i](假设double是8个字节),不会是未定义的行为吗?
我的意思是这个代码不起作用,因为它不打印cp [0]。
答案 0 :(得分:4)
A1:是的,当它访问cp [8]时,它将是未定义的行为。
A2:是的,它也不会打印cp [0]。
如图所示,它打印有效值0..7的字节7,8,5,6,3,4,2,1。因此,如果您从书中正确复制了代码,那么本书的代码就会出现错误。检查书的勘误页面(如果有的话)。
它解开循环也很奇怪;更简单的表述是:
for (int i = sizeof(double); i-- > 0; )
printBinary(cp[i]);
据推测,还有一个很好的理由以相反的顺序打印字节;它不明显是什么。
答案 1 :(得分:2)
这看起来像是书中代码中的拼写错误。第二个电话应该是printBinary(cp[i-2])
。
虽然这有点奇怪,因为它们正在颠倒字节顺序与实际存储器中的内容相比(IEEE 754浮点数没有关于字节序的规则,所以我猜它在他的平台上是有效的),并且因为他在计算2而不是1。
写
会更简单for(int i = 0; i != sizeof(double) ; ++i) printBinary(cp[i]);
或(如果反转字节很重要)使用标准惯用法来计算倒计时的循环
for(int i = sizeof(double); (i--) > 0;) printBinary(cp[i]);
答案 2 :(得分:0)
您可以通过将双精度转换为无符号长整数,以与字节序无关的方式执行此操作。然后,您可以对整数使用简单的位移来访问和打印位,从位0到位63.
(我编写了一个名为“print_raw_double_binary()”的C函数来执行此操作 - 有关详细信息,请参阅我的文章Displaying the Raw Fields of a Floating-Point Number。)