在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;
它有效,但它相当丑陋,我不知道它有多便携 . 有一个更好的方法吗?是否有一种不那么丑陋,可移植的方法从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;
}
3 回答
您通常不能使用frexp(), frexpf(), frexpl()提取值吗?
我喜欢你的解决方案!它让我走上正轨 .
我建议一件事 - 为什么不一次得到一堆比特,几乎总是消除任何循环?我实现了一个float-to-bigint函数,如下所示:
(顺便说一句,我不知道一个简单的方法来放入浮点幂的两个常量,所以我将float_pow_2定义如下):
如果float总是包含一个整数值,只需将其强制转换为int:float_to_int =(unsigned long)输入 .
BTW,77e12溢出浮动 . 一个double会保持它,但是你需要这个演员:( unsigned long long)输入 .