简体   繁体   English

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

[英]convert double number to (IEEE 754) 64-bit binary string representation in c++

I have a double number, I want to represent it in IEEE 754 64-bit binary string. 我有一个双号,我想用IEEE 754 64位二进制字符串表示它。 Currently i'm using a code like this: 目前我正在使用这样的代码:

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

The above code just works fine without any problem. 上面的代码工作正常没有任何问题。 But If you see, i'm using reinterpret_cast and using unsigned long. 但如果你看到,我正在使用reinterpret_cast并使用unsigned long。 So, this code is very much compiler dependent. 所以,这段代码非常依赖于编译器。 Could anyone show me how to write a code that is platform independent and without using any libraries. 任何人都可以告诉我如何编写独立于平台且不使用任何库的代码。 i'm ok, if we use the standard libraries and even bitset, but i dont want to use any machine or compiler dependent code. 我没关系,如果我们使用标准库甚至bitset,但我不想使用任何机器或编译器相关的代码。

Thanks in advance. 提前致谢。

If you're willing to assume that double is the IEEE-754 double type: 如果你愿意假设double是IEEE-754双重类型:

#include <cstdint>
#include <cstring>

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

If you don't even want to make that assumption: 如果你甚至不想做出这样的假设:

#include <cstring>

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

Why not use the union? 为什么不使用联盟?

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

The simplest way to get this is to memcpy the double into an array of char : 获得这个的最简单方法是将double memcpychar数组中:

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

and then extract the bits from double_as_char . 然后从double_as_char提取位。 C and C++ define that in the standard as legal. C和C ++在标准中将其定义为合法。

Now, if you want to actually extract the various components of a double , you can use the following: 现在,如果要实际提取double的各个组件,可以使用以下命令:

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

Since the value returned by frexp is in [0.5, 1) , you need to shift it one extra bit to get all the bits in the mantissa as an integer. 由于frexp返回的值在[0.5, 1) frexp [0.5, 1) ,因此需要将其移位一位以使尾数中的所有位为整数。 Then you just need to map that into the binary represenation you want, although you'll have to adjust the exponent to include the implicit bias as well. 然后你只需要将它映射到你想要的二进制表示,尽管你必须调整指数以包含隐式偏差。

The function print_raw_double_binary() in my article Displaying the Raw Fields of a Floating-Point Number should be close to what you want. 我的文章中显示浮点数的原始字段的函数print_raw_double_binary()应该接近你想要的。 You'd probably want to replace the casting of double to int with a union, since the former violates "strict aliasing" (although even use of a union to access something different than what is stored is technically illegal). 您可能希望用union替换double到int的转换,因为前者违反了“严格别名”(尽管使用联合访问不同于存储的东西在技术上是非法的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM