我想知道为什么下面的代码打印“错误”。
double x = 0x8000000000000000;
signed long long v1 = (signed long long)(x);
signed long long v2 = *(signed long long *)(&x);
printf( v1 == v2? "correct\n" : "wrong\n" );
我尝试通过以下代码分别打印出 v1 和 v2 的二进制表示形式:
printf( "v1 = 0b" );
for ( int i = 63; i > 0; i-- ) {
printf( "%d", ( ( v1 >> i ) & 1 ) );
}
printf( "\n" );
printf( "v2 = 0b" );
for ( int i = 63; i > 0; i-- ) {
printf( "%d", ( ( v2 >> i ) & 1 ) );
}
printf( "\n" );
事实证明 v1 是正确的,但 v2 是0b010000111110000000000000000000000000000000000000000000000000000
。
有谁能好心地告诉我这里发生了什么吗?
另外,我想知道 C 标准是否提供了任何打印出二进制或十六进制底层表示的方法,以便我的打印方案可以用一行函数调用来代替?
在第一种情况下
编译器执行从
double
到 的转换signed long long
。第二种情况
编译器将存储的双精度型的内部表示解释为类型的对象
signed long long
。请注意浮点数在内部以特殊格式存储。
来自 C23 标准草案 n3088:
至于您的最后一个问题,如果我没有记错的话,在 C23 标准中引入了转换说明符
b
,允许以二进制表示形式输出整数。至于 C++,从 C++20 标准开始,您可以使用格式说明符
b
或B
内部格式输出(参见标题的描述<format>
)