Given a double
value:
double value = 123.456;
How would I obtain an unscaled representation of the value (123456) and scale(3)?
This was fairly trivial with decimal
because it's not an IEEE-754 floating point implementation, but it seems much harder to do with double
and float
values.
All I have so far is methods that obtain the sign, exponent and significand/mantissa, but I've no idea what I need to do with these values to obtain the unscaled representation and scale:
private static int GetSign(double value)
{
long bits = BitConverter.DoubleToInt64Bits(value);
return bits >> 63 == 0 ? 1 : -1;
}
private static int GetExponent(double value)
{
long bits = BitConverter.DoubleToInt64Bits(value);
return (int)((bits >> 52) & 0x7FF) - 1023;
}
private static long GetMantissa(double value)
{
long bits = BitConverter.DoubleToInt64Bits(value);
return bits & 0xFFFFFFFFFFFFF;
}
(Of course, these methods could be simplified, passing in the bits, instead of obtaining them every time from double
)
As per Sweeper's comment:
So would you expect double value = 123.4560 to have the unscaled value 1234560 and scale 4? if so, that is impossible because 123.456 and 123.4560 are the same value of type double. Note however, 123.456m and 123.4560m are different.
Insignificant trailing zeros can be ignored; i.e. 123.4560 should still have a scale of 3.
As per Sweeper's second comment:
This is not just about "insignificant trailing zeros". 123.456000000000003 has the same double representation as 123.456 too. It is exactly 123.456000000000003069544618484. Are you sure you want to get this value unscaled?
I gave this a test...
double a = 123.456;
double b = 123.456000000000003069544618484;
Console.WriteLine(a); // 123.456
Console.WriteLine(b); // 123.456
In this case, why does .NET ignore the trailing zeros and digits when printing the value?
(No, I would not want 123456000000000003069544618484 as an unscaled value).