I am writing a parser where I need to parse numbers.
Numbers are in the JSON format, i.e. simplified, something like:
[+|-] integral [. fractional] [e|E exponent]
So these are the 3 parts of the number I have. Each part is an integer.
For example:
0.4
Integral = 0
Fractional = 4
Exponent = 0
2.84e+6
Integral = 2
Fractional = 84
Exponent = 6
I know how to compute the number in Java in a very crude manner. Something like this:
long integral;
long fractional;
int exp;
double decimal = fractional;
while (decimal >= 1.0) {
decimal *= 0.1;
}
var n = (integral + decimal) * Math.pow(10, exp);
But this has terrible properties like losing precision completely, overflowing etc. specially for very large numbers (e.g. 10e99, 2.7e-23).
Is there a way to create a number in Java from its constituent parts such that the number keeps the properties as close as possible to the floating point literal?
My current idea is to try to create the exact bits in memory that would represent the floating point number using the IEEE 754 representation Java (and many languages) uses.
This blog post helped me understand the floating point representation, but I am still kind of stuck.
My current try to do that uses a ByteBuffer
which can do:
ByteBuffer buffer = ByteBuffer.allocate(8);
buffer.put(<bits representing the number exactly in floating point>);
buffer.flip();
double n = buffer.getDouble();
The "only" problem being, figuring out the right bits, which is not trivial (if someone knows a method to do that , please do share).
EDIT: Performance is important, so I am trying to avoid creating a String then throwing it at Double.parseDouble(str)
... as that feels pretty expensive compared to writing the bits into memory... but I might be wrong and this is indeed the most "efficient" option? Really don't know at this point, hopefully I can benchmark when I have a few options.