Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does the value of the number not match

const MAX_VAL = 9_999_999_999_999_999;
const withValueLimit = (inputObj: any) => {
  const { value } = inputObj;
  console.log(`${value} < ${MAX_VAL} == ${value <= MAX_VAL}`)
  if (value <= MAX_VAL) return true;
  return false;
};

MAX_VAL evaluates to 10_000_000_000_000_000

I know that value that I entered is greater than MAX_SAFE_INTEGER
but I need to make a comparison, and to not allow values like MAX_VAL+0.1 and higher

Is it possible to manage that?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

I know that value that I entered is greater than MAX_SAFE_INTEGER

That’s the problem. The literal 9_999_999_999_999_999 actually defines the number value 10,000,000,000,000,000, not 9,999,999,999,999,999:

console.log((9_999_999_999_999_999).toLocaleString());
// => "10,000,000,000,000,000"

You just cannot reliably work with numbers in that range using the number type. (Or rather, they’re reliable, but not precise anymore; at that scale, only even numbers [multiples of 2] can be represented. At even larger scales, only multiples of four. Etc.)

For integer numbers beyond the number range, you can use BigInt:

const MAX_VAL = 9_999_999_999_999_999n;
const withValueLimit = (inputObj/*: any*/) => {
    let { value } = inputObj;
    if (typeof value === "number") {
        value = BigInt(value);
    }
    // console.log(`${value} < ${MAX_VAL} == ${value <= MAX_VAL}`)
    return value <= MAX_VAL;
};
console.log(withValueLimit({value: 1n}));                       // true
console.log(withValueLimit({value: 10_000_000_000_000_000n}));  // false
console.log(withValueLimit({value: 47}));                       // true

In that example, I’ve allowed the object to either have a number or BigInt as value.

If you need to support obsolete JavaScript engines that don’t have BigInt, you can use any of several "big number" libraries that were developed for the purpose. (Just search for "JavaScript big number".)


In a comment you’ve mentioned getting this error:

RangeError: 25.5 can’t be converted to BIGINT because it’s not an integer

I should have thought of that case. You can handle it with Math.round, Math.floor, or Math.ceil to convert the fractional number to an integer value for the purposes of the check. For instance, if you want to round up (25.5 => 26) in order to perform the check, you’d use Math.ceil:

const withValueLimit = (inputObj/*: any*/) => {
    let { value } = inputObj;
    if (typeof value === "number") {
        value = BigInt(Math.ceil(value));
        //             ^^^^^^^^^^^^^^^^
    }
    // console.log(`${value} < ${MAX_VAL} == ${value <= MAX_VAL}`)
    return value <= MAX_VAL;
};
const MAX_VAL = 9_999_999_999_999_999n;
const withValueLimit = (inputObj/*: any*/) => {
    let { value } = inputObj;
    if (typeof value === "number") {
        value = BigInt(Math.ceil(value));
        //             ^^^^^^^^^^^^^^^^
    }
    // console.log(`${value} < ${MAX_VAL} == ${value <= MAX_VAL}`)
    return value <= MAX_VAL;
};
console.log(withValueLimit({value: 1n}));                       // true
console.log(withValueLimit({value: 10_000_000_000_000_000n}));  // false
console.log(withValueLimit({value: 47}));                       // true
console.log(withValueLimit({value: 25.5}));                     // true
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading