I am trying extract the mantissa and exponent part from the double. For the test data '0.15625', expected mantissa and exponent are '5' and '-5' respectively (5*2^-5).
double value = 0.15625;
double mantissa = frexp(value, &exp);
Result: mantissa = 0.625 and exp = -2
.
Here the mantissa returned is a fraction. For my use case (ASN.1 encoding), mantissa should be integer. I understand by right-shifting the mantissa and adjusting the exponent, I can convert binary fraction to the integer. In the eg, 0.625 base 10
is 0.101 base 2
, so 3
bytes to be shifted to get the integer. But I am finding it difficult to find a generic algorithm.
So my question is, how do I calculate the number bits to be shifted to convert a decimal fraction to a binary integer?
CodePudding user response:
#include <cmath> // For frexp.
#include <iomanip> // For fixed and setprecision.
#include <iostream> // For cout.
#include <limits> // For properties of floating-point format.
int main(void)
{
double value = 0.15625;
// Separate value into significand in [.5, 1) and exponent.
int exponent;
double significand = std::frexp(value, &exponent);
// Scale significand by number of digits in it, to produce an integer.
significand = scalb(significand, std::numeric_limits<double>::digits);
// Adjust exponent to compensate for scaling.
exponent -= std::numeric_limits<double>::digits;
// Set stream to print significand in full.
std::cout << std::fixed << std::setprecision(0);
// Output triple with significand, base, and exponent.
std::cout << "(" << significand << ", "
<< std::numeric_limits<double>::radix << ", " << exponent << ")\n";
}
Sample output:
(5629499534213120, 2, -55)
(If the value is zero, you might wish to force the exponent to zero, for aesthetic reasons. Mathematically, any exponent would be correct.)