如何输出浮点数的二进制表示?

时间:2010-10-02 22:11:55

标签: c++ binary floating-point

我是编程新手,我已经完成了Web开发,但我目前正在尝试学习真正的编程。我的问题已经回答here

union ufloat {
  float f;
  unsigned u
};

ufloat u1;
u1.f = 0.3f;

我不知道它是如何工作的。 0.3部分做了什么?我在文中找不到它。这如何将浮点数转换为二进制?因为cout<<u1.u;似乎没有给我答案。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:3)

0.3只是一个测试值。打印u1.u不会为您提供二进制表示,但二进制表示的值被解释为基数为10的整数。要获取二进制值,您必须convert u1.u为二进制值。

转换的另一种方法是使用bitwise operators

例如:

unsigned x = 11;
do
{
    cout << (x & 1); // print last bit
    x = x >> 1; // get rid of the printed bit
} while ( x );

请注意,这将以相反的顺序打印位(最不重要的是先打印)。我将由你来解决这个问题(你可以在数组中使用递归或存储值,然后反转打印数组)。

我还建议您阅读unions。基本上,unsigned将占用与float相同的内存空间,允许您规避使用按位运算符查找float的二进制表示的限制。

答案 1 :(得分:2)

答案在于工会如何在C / C ++中运作。联合允许您使用内存中的相同空间表示多种类型的数据。因此,在您的示例中,ufloat联合将float和整数存储在同一内存空间中。根据您访问此内存空间的方式(通过f数据成员或u数据成员),程序将分别将内存区域解释为浮点或无符号整数。

当您通过u数据成员访问内存区域时,程序认为您希望将内存区域表示为二进制整数,而不是浮点值。但由于内存区域实际上存储了浮点值(0.3f),因此它只是输出该值,就像它是二进制整数一样。因此,您将获得浮动的二进制表示。

答案 2 :(得分:2)

过于迂腐,这不是有效的C或C ++。

我怀疑现有的每个编译器都支持它,但就标准而言,编写一个union的一个成员然后读另一个成员是无效的。但是,要知道floatunsigned大小相同,您已经使用了一些实现定义的信息,因此您可以使用更多信息。它很常见,而且通常都有效。

但是,作为参考,您始终可以将内存检查为一系列字节:

#include <iostream>
#include <iomanip>
#include <climits>
#include <cassert>

int main() {
    float f = 0.3;
    unsigned char *buf = (unsigned char*)(&f);

    // Now we just have to print the sucker.

    assert(CHAR_BIT == 8); // otherwise hex isn't much use

    // This shows the byte representation, low addresses on the left.
    // On a little-endian machine, you might like to count down for 
    // convenience of reading.
    for (int i = 0; i < sizeof f; ++i) {
        std::cout << std::hex << std::setw(2) << std::setfill('0');
        std::cout << static_cast<unsigned int>(buf[i]) << ' ';
    }
    std::cout << '\n';
}

输出(在我的机器上):

9a 99 99 3e

如果您更愿意使用unsigned而不是unsigned char

#include <cstring>

float f = 0.3;
unsigned u;
assert(sizeof f == sizeof u);
std::memcpy(&u, &f, sizeof f);

std::cout << std::hex << u << "\n";

输出(在我的机器上):

3e99999a