Reputation: 4020
According to Is floating point math broken?, I know 0.1 cannot represent exactly in floating point numbers and will be rounded to some values.
According to Is hardcode float precise if it can be represented by binary format in IEEE 754?, some numbers with integers values (e.g.:1,2,10...) can be represented perfectly (no rounding errors).
So my question is, if x ,y and a are values with integers, does x/y rounds to the same value as (x * a)/(y * a)?
For example, does 1/10 rounds to the values same as 10/100, as well as 123/1230?
Upvotes: 2
Views: 182
Reputation: 1074355
numbers with integers values (e.g.:1,2,10...) can be represented perfectly (no rounding errors)
Only within the range -Number.MAX_SAFE_INTEGER - 1
(-9,007,199,254,740,992) through Number.MAX_SAFE_INTEGER + 1
(9,007,199,254,740,992), inclusive. Outside that range, integers are indeed rounded:
var n = Number.MAX_SAFE_INTEGER;
console.log("n =", n);
console.log("n + 1 =", n + 1);
console.log("n + 2 =", n + 2); // rounds
For example, does 1/10 rounds to the values same as 10/100, as well as 123/1230?
For those sorts of examples, I think you'll end up with the same value, yes. But there are two things related to this worth mentioning:
I don't think JavaScript allows this, but some implementations that otherwise use IEEE-754 numbers allow intermediate values within a calculation with more precision than can be held by the format, and thus by the inputs and outputs of the calculation. [Java, for instance, has both "loose" and "strict" floating-point (the strictfp
keyword and related runtime flags), where "loose" allows intermediate values with more precision and strict does not (for interoperability).] So in a "loose" FP environment and a sufficiently-complex calculation, if an implementation holds intermediate values in a more-precise form, the results can be slightly different from if every stage of the calculation were handled with rounding to the format's constraints. But again, I can't find anything in the JavaScript spec allowing that other than related to some trigonometric functions, and I don't think that would apply to your simple division examples above even if it did.
As mentioned above, the magnitude of a decimal number can affect whether it's held precisely (0.1 isn't, 1 is, 9,007,199,254,740,993 isn't). But within the whole numbers in the range discussed above, since they're all held perfectly, the inputs will be precisely what they look like.
If
x
,y
anda
are number with integer values, doesx/y
rounds to the same value as(x*a)/(y*a)
?
That's a slightly different question, and it depends on the magnitude of the numbers. If the result of x*a
or the result of y*a
takes the value out of the range discussed at the beginning of this answer, you may get a different result for those expressions. So with large-ish integers, potentially no, they may not have the same result:
var x = 945127356192545;
var y = 123456789012345;
var a = 27;
var r1 = x/y;
console.log("x/y =", r1);
var r2 = (x*a)/(y*a);
console.log("(x*a)/(y*a) =", r2);
console.log("same?", r1 == r2);
Upvotes: 2