Skip to content Skip to sidebar Skip to footer

At What Point Does Comparing Between An "integer" And A "float" Equals `true`?

I understand about Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER. I understand that Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 equals true. But I've only rec

Solution 1:

Asking when comparing fails is the wrong question. Comparing two numbers always works correctly; it evaluates to true if and only if the two numbers being compared have the same value.

The problem actually occurs in earlier operations. Converting a numeral in source code to a Number, adding numbers, and other operations introduce errors when the exact real-number mathematical value is rounded to a value representable in floating-point.

JavaScript uses IEEE-754 binary64, which has a 53-bit significand (the fraction portion of a floating-point number). This means any number with a magnitude of 2 or greater does not have any bits that can represent values less than 1—they have no fraction portion. So, when any number 2 or greater is converted to a JavaScript Number, the result is an integer.

But smaller numbers are rounded too. From 2 to 2, the least significant bit available represents 2, or ½. So any number in this interval that is converted to a Number must produce either an integer or an integer plus ½. That means some numbers, like 2251799813685248.6, will produce non-integers (2251799813685248.5), while others, like 2251799813685248.8 will produce integers (2251799813685249).

At every magnitude below 2, there are some numbers that will be rounded to integers when converted to Number and some numbers that will not be rounded to integers. (Above 2, all numbers are rounded to integers.) At smaller magnitudes, only numbers closer to integers are rounded to integers—the format becomes more “sensitive” as the magnitude decreases.

Solution 2:

There is no such thing, because Javascript numbers have limited precision, or significant digits (effectively).

const n1 = 1e-10;
const n2 = 1e-30;
console.log(n1 - n2 === n1);

Even a very small number like 1e-10 will have imprecise behavior when manipulated in combination with numbers significantly smaller than it. The same sort of thing is happening with your snippet - ~1e15 (close to the value of your 1007199254740991) is too large in comparison to 0.123.

There's also the famous imprecise 0.1 + 0.2:

console.log(0.1 + 0.2);

In addition to significant digits being effectively limited, numbers which cannot be precisely represented in binary will have this sort of problem.

Solution 3:

You can't find a "max safe float" in JavaScript. It simply doesn't exist.

@CertainPerformance is right, there's a limited precision in JS. Besides, remember that a number in a programming language is stored by 0 or 1 bits, and remember that you can have infinite decimals, so... can you have infinite 0's and 1's? .

As any computer can store infinite numbers, there's no max safe float number.

Post a Comment for "At What Point Does Comparing Between An "integer" And A "float" Equals `true`?"