浮点逆二进制表示

时间:2017-03-21 17:16:58

标签: c++ floating-point c++14 ieee-754

我对以下几段代码感到困惑:

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,它指出应该有一个单独的符号位。第一个程序的最后一个输出似乎是使用了两个补码......

其他的只是完全令人困惑..所有零和一些随机输出,即使使用相同的代码,只是截断..

我误解了什么?我在代码中的某个地方得到了未定义的行为吗?不懂语法?或浮动由于某种原因不能表示为位集?

2 个答案:

答案 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;
}

对于不同的语言和版本,哪种类型的投票方式更好,这是相互矛盾的意见,我不会在这里深入讨论。