以二进制打印双倍

时间:2010-05-02 17:45:43

标签: c++ binary printing double

在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]。

3 个答案:

答案 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。)