将浮点转换为字节数组的程序中出现运行时错误

Runtime error in a program supposed to convert a float to a byte array

本文关键字:程序 运行时错误 数组 字节数 转换 字节      更新时间:2023-10-16

我得到了一个浮点变量,想知道它的字节表示是什么。所以我去了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 ffffff b2 54 4a

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

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

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

struct中用unsigned char替换char,并在末尾添加一个return 0;解决了所有问题:http://ideone.com/ienG2b.

您的方法有很多错误。以下是如何打印通用对象的二进制表示:

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]);
    }
}

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