0

我得到了一个浮点变量,想知道它的字节表示是什么。所以我去了 IDEOne 并编写了一个简单的程序来做到这一点。但是,令我惊讶的是,它会导致运行时错误:

#include <stdio.h>
#include <assert.h>

int main()
{
    // These are their sizes here. So just to prove it.
    assert(sizeof(char) == 1);
    assert(sizeof(short) == 2);
    assert(sizeof(float) == 4);

    // Little endian
    union {
        short s;
        char c[2];
    } endian;
    endian.s = 0x00FF; // would be stored as FF 00 on little
    assert((char)endian.c[0] == (char)0xFF);
    assert((char)endian.c[1] == (char)0x00);

    union {
        float f;
        char c[4];
    } var;
    var.f = 0.0003401360590942204;
    printf("%x %x %x %x", var.c[3], var.c[2], var.c[1], var.c[0]); // little endian
}

在 IDEOne 上,它输出:

39 ffffffb2 54 4a

以及运行时错误。为什么会出现运行时错误,为什么b2实际上是ffffffb2?我的猜测b2是符号扩展。

4

3 回答 3

6

char是有符号类型。如果它是 8 位长并且您在其中放入任何大于 127 的内容,它将溢出。有符号整数溢出是未定义的行为,因此使用转换说明符打印一个有符号值,该说明符需要一个无符号值(%x需要unsigned int,但在传递给可变参数函数时char被提升[隐式转换] )。signed intprintf()

底线-更改char c[4]unsigned char c[4],它将正常工作。

于 2013-07-25T21:02:48.780 回答
5

替换char为并unsigned char在末尾struct添加一个修复了所有问题:http: //ideone.com/ienG2breturn 0;

于 2013-07-25T21:03:21.867 回答
2

你的方法是各种各样的错误。以下是打印一般对象的二进制表示的方法:

template <typename T>
void hexdump(T const & x)
{
    unsigned char const * p = reinterpret_cast<unsigned char const *>(&x);
    for (std::size_t i = 0; i != sizeof(T); ++i)
    {
        std::printf("%02X", p[i]);
    }
}

结果是您始终可以将任何对象解释为字符数组,从而揭示其表示。

于 2013-07-25T21:09:24.433 回答