Ninja
Ninja

Reputation: 453

How to deal with big numeric values from response in javascript?

I have to read a JSON response which contains the value which is greater than MAX_SAFE_INTEGER without loss of precision. Like I had values

 value1 =  232333433534534634534411

And I have to process that value and convert to

 value2 =  +232333433534534634534411.0000

without any loss of precision?

Upvotes: 2

Views: 1553

Answers (2)

Lionel Rowe
Lionel Rowe

Reputation: 5926

This can't be done with standard JSON.parse:

JSON.parse('{"prop": 232333433534534634534411}')
// {prop: 2.3233343353453462e+23}

If you have control over the API producing the JSON

You can use a string instead, then create a BigInt out of it (assuming legacy browser support isn't required).

const result = JSON.parse('{"prop": "232333433534534634534411"}')
const int = BigInt(result.prop)
// 232333433534534634534411n

If you need to perform decimal arithmetic on this result with a precision of 4 decimal places, you can multiply it by 10000n, for example:

const tenThousandths = int * 10000n // 2323334335345346345344110000n
const sum = tenThousandths + 55000n + 21n * 2n // 2323334335345346345344165042n
const fractionalPart = sum % 10000n // 5042n
const wholePart = sum / 10000n // 232333433534534634534416n (floor division)
const reStringified = `${wholePart}.${fractionalPart}` // "232333433534534634534416.5042"

const newJson = JSON.stringify({prop: reStringified})
// '{"prop":"232333433534534634534416.5042"}'

For legacy browser support, you could do similar with a library such as BigInteger.js.

If you don't control the API

In this case, you'll need a custom JSON parsing library, such as lossless JSON.

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386680

You could split by dot and treat the digits after the dot.

const convert = string => {
    const values = string.split('.');
    values[1] = (values[1] || '').padEnd(4, 0).slice(0, 4);    
    return values.join('.');
};

console.log(convert('232333433534534634534411'));
console.log(convert('232333433534534634534411.12345'));

Upvotes: 1

Related Questions