将float转换为bigint(也称为可移植方式以获取二进制指数和尾数)

ama*_*ion 4 c++ floating-point ieee-754 bigint

在C++中,我有一个bigint类,可以保存任意大小的整数.

我想将大浮点数或双数字转换为bigint.我有一个工作方法,但它有点像黑客.我使用IEEE 754数字规范来获得输入数字的二进制符号,尾数和指数.

这是代码(这里忽略了Sign,这并不重要):

 float input = 77e12;
 bigint result;

 // extract sign, exponent and mantissa, 
 // according to IEEE 754 single precision number format
 unsigned int *raw = reinterpret_cast<unsigned int *>(&input); 
 unsigned int sign = *raw >> 31;
 unsigned int exponent = (*raw >> 23) & 0xFF;
 unsigned int mantissa = *raw & 0x7FFFFF;

 // the 24th bit is always 1.
 result = mantissa + 0x800000;

 // use the binary exponent to shift the result left or right
 int shift = (23 - exponent + 127);
 if (shift > 0) result >>= shift; else result <<= -shift;

 cout << input << " " << result << endl;
Run Code Online (Sandbox Code Playgroud)

它有效,但它相当丑陋,我不知道它有多便携.有一个更好的方法吗?是否有一种不那么丑陋,可移植的方法从float或double中提取二进制尾数和指数?


谢谢你的回答.对于后代,这是一个使用frexp的解决方案.由于循环它的效率较低,但它适用于float和double,不使用reinterpret_cast或依赖于浮点数表示的任何知识.

float input = 77e12;
bigint result;

int exponent;
double fraction = frexp (input, &exponent);
result = 0;
exponent--;
for (; exponent > 0; --exponent)
{
    fraction *= 2;
    if (fraction >= 1)
    {
        result += 1;
        fraction -= 1;
    }
    result <<= 1;
}   
Run Code Online (Sandbox Code Playgroud)

Kor*_*icz 8

您通常不能使用frexp(),frexpf(),frexpl()来提取值吗?

  • 你当然可以,但在C++中,最好使用`std :: frexp()`,它为`float`,`double`和`long double`参数重载. (3认同)