In C ++, I have a bigint class that can contain an integer of arbitrary size.
I would like to convert large floats or double numbers to bigint. I have a working method, but it’s a bit hacked. I used the IEEE 754 number specification to get the binary sign, mantissa, and input number metric.
Here is the code (The sign is ignored here, it doesn’t matter):
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;
It works, but it's pretty ugly, and I don't know how portable it is. Is there a better way to do this? Is there a less ugly, portable way to extract a binary mantissa and an exponent from a float or double?
Thanks for answers. For posterity, this is a solution using frexp. It is less efficient due to the loop, but it works the same for float and double, doesn't use reinterpret_cast or depends on any knowledge about floating point representations.
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; }
source share