edit: To clarify, by "decimal exponent of a double" I mean the magnitude of the value or the base 10 exponent of the value. For instance 3456.7 -> 3.4567E3 -> Scientific Exponent = 3
I need to find the decimal exponent of a double.
I've been researching ways this is done, and I've found various methods.
For instance to estimate the exponent Microsoft's STL uses an interesting lookup table:
However, the method I came up with seems the simplest:
// v -> value
// x -> ScientificExponent
// 10^x <= v < 10^(x+1)
// x <= log(v) < x+1
ScientificExponent = (Value == 0) ? 1 : floor((log10(fabs(Value))));
I'm wondering why this isn't used. Are there cases where this doesn't work? Is this assumed to be too slow?
Are there any edge/corner cases I am not considering (maybe subnormal values being too small to get an accurate log calculation from)?
I'd appreciate any insight people can provide.
Also, if this is a good way to do this, is there a good way to calculate only the integer part of log10? It seems a waste to calculate the log to many decimal places only to throw it away with the floor
.
floor((log10(fabs(Value))))
is inadequate to compute the decimal exponent of a number.
Consider using IEEE-754 binary64 (“double precision”). Let Value
be 0.09999999999999999167332731531132594682276248931884765625 = 9.999999999999999167332731531132594682276248931884765625•10−2, which is a representable value.
log10 of 0.09999999999999999167332731531132594682276248931884765625 is approximately ?−1.000000000000000036162279995748268157562864421389843161585017393347605917054938808868324457086236340. This number is not representable in binary64; the closest representable value is −1.
So a good log10
implementation will return −1 for input 0.09999999999999999167332731531132594682276248931884765625.
Then floor((log10(fabs(Value))))
produces −1, but the correct result would be −2.