Высокоточные вычисления JavaScript и BIGINT JSON.parse

внешний интерфейс Безопасность JavaScript jQuery

Когда JavaScript обрабатывает целые числа, вы столкнетесь с некоторыми очень странными проблемами, такими как фон, который возвращает вам супер длинное число, а затем js внезапно обнаруживает, что вычисление неверно при вычислении, либо обратное значение равно 0, либо вычисление не то, что вы хотите , Результат.Это включает в себя очень простое знание, которое является безопасным целым числом.

Безопасное целое число

Number.MAX_SAFE_INTEGER // 9007199254740991
9007199254740991+2 // 9007199254740992

Сначала мы получаем число в пределах безопасного диапазона, а затем выполняем над ним простое сложение, нормальный результат должен быть 9007199254740993, но мантисса здесь всего 2. Интересно также, что вы можете это проверить. Поскольку все целые числа в js вызваны типом с плавающей запятой (значение двойной точности в 64-битном двоичном формате IEEE 754), хотя допустимый диапазон относительно велик, точность вычислений не очень хорошая.

точность расчета

После разговора о безопасных целых числах кратко поговорим о точности вычислений.

0.1+0.2 //0.30000000000000004

Принцип тот же, что и выше, решение тоже очень простое

использоватьmath.jsбиблиотека может решить

// prevent round-off errors showing up in output
var ans = math.add(0.1, 0.2);       //  0.30000000000000004
math.format(ans, {precision: 14});  // '0.3'

BIGINT встречается в JSON.parse

Более распространенный сценарий заключается в том, что в фоновом режиме возвращается строка JSON, но число БОЛЬШОЕ, что вызывает ошибку синтаксического анализа, обычно 16 бит.

var c='{"num": 90071992547409999}'
JSON.parse(c) // {num: 90071992547410000}

Например, мы используем ajax jQuery, чтобы включить функцию json:true, и jQuery автоматически проанализирует это, что приведет к недостаточной точности, поэтому вы можете использовать его здесь.json-bigint

var JSONbig = require('json-bigint');

var json = '{ "value" : 9223372036854775807, "v2": 123 }';
console.log('Input:', json);
console.log('');

console.log('node.js bult-in JSON:')
var r = JSON.parse(json);
console.log('JSON.parse(input).value : ', r.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSON.stringify(r));

console.log('\n\nbig number JSON:');
var r1 = JSONbig.parse(json);
console.log('JSON.parse(input).value : ', r1.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSONbig.stringify(r1));

// output

Input: { "value" : 9223372036854775807, "v2": 123 }

node.js bult-in JSON:
JSON.parse(input).value :  9223372036854776000
JSON.stringify(JSON.parse(input)): {"value":9223372036854776000,"v2":123}


big number JSON:
JSON.parse(input).value :  9223372036854775807
JSON.stringify(JSON.parse(input)): {"value":9223372036854775807,"v2":123}

Если вы не хотите вводить дополнительные библиотеки, вы можете обратиться к этой функции

let stringedJSON = origJSON.replace(/:\s*([-+Ee0-9.]+)/g, ': "uniqueprefix$1"');

let o = JSON.parse(stringedJSON, (key, value) => {
  // only changing strings
  if (typeof value !== 'string') return value;
  // only changing number strings
  if (!value.startsWith('uniqueprefix')) return value;
  // chop off the prefix
  value = value.slice('uniqueprefix'.length);
  // pick your favorite arbitrary-precision library
  return new Big(value);
});

использованная литература