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?
>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