在c ++中将双数转换为(IEEE 754)64位二进制字符串表示

时间:2011-12-23 22:27:21

标签: c++ c string double ieee-754

我有一个双号,我想用IEEE 754 64位二进制字符串表示它。 目前我正在使用这样的代码:

double noToConvert;
unsigned long* valueRef = reinterpret_cast<unsigned long*>(&noToConvert);

bitset<64> lessSignificative(*valueRef);
bitset<64> mostSignificative(*(++valueRef));

mostSignificative <<= 32;
mostSignificative |= lessSignificative;

RowVectorXd binArray = RowVectorXd::Zero(mostSignificative.size());
for(unsigned int i = 0; i <mostSignificative.size();i++)
{
    (mostSignificative[i] == 0) ? (binArray(i) = 0) : (binArray(i) = 1);
} 

上面的代码运行正常没有任何问题。但如果你看到,我正在使用reinterpret_cast并使用unsigned long。所以,这段代码非常依赖于编译器。任何人都可以告诉我如何编写独立于平台且不使用任何库的代码。我很好,如果我们使用标准库甚至bitset,但我不想使用任何机器或编译器相关的代码。

提前致谢。

4 个答案:

答案 0 :(得分:5)

如果您愿意假设double是IEEE-754双重类型:

#include <cstdint>
#include <cstring>

uint64_t getRepresentation(const double number) {
    uint64_t representation;
    memcpy(&representation, &number, sizeof representation);
}

如果你甚至不想做出这样的假设:

#include <cstring>

char *getRepresentation(const double number) {
    char *representation = new char[sizeof number];
    memcpy(representation, &number, sizeof number);
    return representation;
}

答案 1 :(得分:2)

为什么不使用联盟?

bitset<64> binarize(unsigned long* input){
    union binarizeUnion   
    {
        unsigned long* intVal;
        bitset<64> bits;
    } binTransfer;
    binTransfer.intVal=input;
    return (binTransfer.bits);
}

答案 2 :(得分:1)

获得此功能的最简单方法是将memcpy双精度转换为char数组:

char double_as_char[sizeof(double)];
memcpy(double_as_char, &noToConvert, sizeof(double_as_char));

然后从double_as_char中提取位。 C和C ++在标准中将其定义为合法。

现在,如果您想要实际提取double的各种组件,可以使用以下内容:

sign= noToConvert<=-0.0f;
int exponent;
double normalized_mantissa= frexp(noToConvert, &exponent);
unsigned long long mantissa= normalized_mantissa * (1ull << 53);

由于frexp返回的值在[0.5, 1)中,因此需要将其移位一位以使尾数中的所有位为整数。然后你只需将它映射到你想要的二进制表示,尽管你也必须调整指数以包含隐式偏差。

答案 3 :(得分:1)

我的文章Displaying the Raw Fields of a Floating-Point Number中的函数print_raw_double_binary()应该接近你想要的。您可能希望用union替换double到int的转换,因为前者违反了“严格别名”(尽管使用联合来访问与存储的内容不同的东西在技术上是非法的)。