Как работать с большими числовыми значениями из ответа в javascript?

#javascript

#javascript

Вопрос:

Я должен прочитать ответ JSON, который содержит значение, большее, чем MAX_SAFE_INTEGER, без потери точности. Как будто у меня были значения

  value1 =  232333433534534634534411
  

И я должен обработать это значение и преобразовать в

  value2 =   232333433534534634534411.0000
  

без потери точности?

Комментарии:

1. @evgengorbunkov BigInt у меня не работает, и пока я использую toString() для преобразования числа в строку, оно теряет точность.

2. что вы делаете после преобразования с числом?

3. @ninaScholz Мне пришлось сравнить его с сохраненным ответом.

4. @Evgengorbunkov Нет, у меня нет внутренних элементов управления

5. есть ли у вас пример сравнения и каков ожидаемый результат?

Ответ №1:

Это невозможно сделать с помощью стандартного JSON.parse :

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

Если у вас есть контроль над API, создающим JSON

Вместо этого вы можете использовать строку, а затем создать BigInt из нее (при условии, что поддержка устаревшего браузера не требуется).

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

Если вам нужно выполнить десятичную арифметику для этого результата с точностью до 4 знаков после запятой, вы можете умножить его на 10000n , например:

 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"}'
  

Для поддержки устаревшего браузера вы могли бы сделать аналогичное с такой библиотекой, какBigInteger.js.

Если вы не управляете API

В этом случае вам понадобится пользовательская библиотека синтаксического анализа JSON, такая как JSON без потерь.

Комментарии:

1. Я ценю это, и это полностью оправдано, но у меня нет контроля над API, и я должен рассматривать его только как число, как если бы я преобразовал его в строку с помощью toString(), это просто теряет точность.

2. @Ninja Библиотека синтаксического анализа JSON — единственный разумный способ пойти дальше. Вы могли бы попробовать какое-нибудь хакерское решение, используя grepping для имени свойства (при условии, что для разных элементов не существует нескольких одинаковых имен свойств), но такой подход всегда будет хрупким.

Ответ №2:

Вы могли бы разделить на точки и обрабатывать цифры после точки.

 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'));  

Комментарии:

1. Я ценю ваши усилия, но проблема в том, что когда я меняю его на string, он уже теряет свою точность

2. почему? просто возьмите JSON без преобразования.

3. в JSON это должна быть строка. в противном случае это просто число, а не JSON .

4. В JSON, который я использую, это было похоже на «MarketValue»: 534534534545335

5. затем возьмите число из строки, выполнив поиск "MarketValue": .