Reputation: 2535
I'm worried that something like 7/2 might become 3.49999999 instead of 3.5 on some computer then round to 3 instead of 4. Is that possible?
I need every computer to re-run the same math exactly. That's the only time I ever have a float: Math.round(intA/intB)
Upvotes: 0
Views: 58
Reputation: 155363
There's two parts of your question:
2
divide to precisely to a multiple of .5
?Math.round
round portably?The answer to both should be yes (though obviously implementers could do some strange stuff). Specifically:
IEE-754 binary floating point values (which JS's Number
is implemented in terms of, specifically the binary64 form) use a scaling factor based on a power-of-2; as such, any integer value representable by Number
can be divided by 2
without precision loss; either it divides evenly (and no scaling factor is needed), or it's odd, and the scaling factor is used to store it internally as basically "original value divided by 2**1
".
Math.round
is required by the spec to round towards positive infinity:
If the fractional portion is exactly 0.5, the argument is rounded to the next integer in the direction of +∞.
Between those two guarantees, you don't need to worry; 7/2
will always be 3.5
precisely, and Math.round(7/2)
will always be 4
. It's only when you divide by non-powers-of-2 (or huge powers-of-2), or you're dividing something that's not a precise integer, that error can creep in.
If you're doing something that produces imprecise results in IEEE-754 binary floating point, it'll be imprecise, but it should be portably imprecise; JS is not C, the spec explicitly requires a double-precision 64-bit binary format IEEE 754, not "whatever the processor happens to provide", so you don't have to worry about esoteric hardware that provides floating point that's incompatible with IEEE-754 (if the hardware doesn't support it, any compliant JS engine would need to implement it in software).
Upvotes: 3