我对以下几段代码感到困惑:
int main()
{
std::cout << std::bitset<32>(10.0f) << std::endl;
std::cout << std::bitset<32>(-10.0f) << std::endl;
float x = 10.0f;
std::bitset<32> bsx(x);
float y = -10.0f;
std::bitset<32> bsy(y);
std::cout << bsx << std::endl;
std::cout << bsy << std::endl;
}
第二个只是(是的,它只是一个截断的第一个):
int main()
{
std::cout << std::bitset<32>(10.0f) << std::endl;
std::cout << std::bitset<32>(-10.0f) << std::endl;
}
我得到以下输出: 第一个:
00000000000000000000000000001010
00000000000000000000000000000000
00000000000000000000000000001010
11111111111111111111111111110110
第二名:
00000000000000000000000000001010
00000000000000010010000001101000
系统是macOS Sierra上的Clang 4.0.0(10.12.3),据我所知,浮点数是32位。
(使用g++ -pedantic -std=c++14
编译。)
我唯一知道浮点数的是IEEE-754,它指出应该有一个单独的符号位。第一个程序的最后一个输出似乎是使用了两个补码......
其他的只是完全令人困惑..所有零和一些随机输出,即使使用相同的代码,只是截断..
我误解了什么?我在代码中的某个地方得到了未定义的行为吗?不懂语法?或浮动由于某种原因不能表示为位集?
答案 0 :(得分:1)
此代码不显示浮点数的二进制表示,不。因为没有std::bitset
constructors采用浮点数。
答案 1 :(得分:0)
它的工作原理如下:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="myselect" id="sel1">
<option val="1">1</option>
<option val="2">2</option>
<option val="3">3</option>
</select>
<select class="myselect" id="sel2">
<option val="1">1</option>
<option val="2">2</option>
<option val="3">3</option>
</select>
我已经添加了另一种格式的显式重读值。 输出是
#include <bitset>
#include <iostream>
inline unsigned U(float f) { return (unsigned&) f; }
int main()
{
std::cout << std::bitset<32>(U(10.0f)) << std::endl;
std::cout << std::bitset<32>(U(-10.0f)) << std::endl;
return 0;
}
(当然,传统的平台特定细节免责声明应放在此处。)
更新:存在内存别名问题导致转换器以下列方式更好地编写(至少对于现代GCC和Clang):
01000001001000000000000000000000
11000001001000000000000000000000
现代编译器将此memcpy()视为&#34; bitcast&#34;运算符并在内部将其转换为适当类型的寄存器移动。如果没有这个,你可以通过别名来解决一些奇怪的问题。 但是,对于ICC来说,这种方法更糟糕,ICC更喜欢不同类型成员的联合:
inline unsigned U(float f) {
unsigned R;
memcpy(&R, &f, sizeof(R));
return R;
}
对于不同的语言和版本,哪种类型的投票方式更好,这是相互矛盾的意见,我不会在这里深入讨论。