#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":
.