I have an "extented double" data-type that stores the exponent in a seperate int variable to increase the range like this:
struct extDouble
{
double Value;
int Exponent;
}
I now need to convert a boost multiprecision float (cpp_bin_float) into this data-type. For values within the range of doubles this is no problem and can be done with
extDouble Number;
Number.Value = BigNumber.convert_to<double>();
Number.Exponent = 0;
(the loss of decimal places is no problem).
But how could I (efficiently) do this with values beyond the range of doubles? I know I could read the exponent directly like this:
Number.Exponent = BigNumber.backend().exponent();
But in order to get the fractional value, I would have to multiply BigNumber
by pow(2, Exponent)
which I want to avoid for performance reasons. Is there a way to read out the fractional value directly or simply set the exponent of BigNumber
to 0? Or does anybody have another idea how to accomplish the whole thing as efficiently as possible (something like frexp or ldexp for boost multiprecision)?
Edit:
To clarify: if there was frexp
for boost multifloats, I would simply do something like this:
Number.Value = frexp(BigNumber, &Number.Exponent);
I thought I was going to post a clever answer based in
ilogb
/scalbn
¹, but then I thought to just check the premise:Works just fine.
frexp
is found via ADL, and resolves to the multiprecision implementation.Generalized a bit and with test cases:
Live On Coliru
Prints
¹ much like here https://en.cppreference.com/w/cpp/numeric/math/frexp