Вопрос

Почему q == 0 в следующем скрипте?

<script>
  var start = 1234567890123456789;
  var end =   1234567890123456799;
  var q = end - start;
  alert(q);
</script>

Я бы подумал, что результат должен быть равен 10.Как правильно вычесть эти два числа?

Это было полезно?

Решение

Потому что числа в JavaScript имеют плавающую точку.Они имеют ограниченную точность.

Когда JavaScript видит очень длинное число, он округляет его до ближайшего числа, которое оно может представить в виде 64-битного числа с плавающей запятой.В вашем сценарии start и end округлить до одного и того же значения.

alert(1234567890123456789);   // says: 1234567890123456800
alert(1234567890123456799);   // says: 1234567890123456800

Не существует встроенного способа выполнения точных арифметических действий с большими целыми числами, но вы можете использовать библиотеку BigInteger, например Вот этот.

Другие советы

Джейсон уже написал причину.В качестве решения вы можете получить библиотеку Javascript BigInt по адресу http://www-cs-students.stanford.edu/~tjw/jsbn/

const subtract = (a, b) => [a, b].map(n => [...n].reverse()).reduce((a, b) => a.reduce((r, d, i) => {
    let s = d - (b[i] || 0)
    if (s < 0) {
        s += 10
        a[i + 1]--
    }
    return '' + s + r
}, '').replace(/^0+/, ''))


Лучше использовать для этих целей библиотеку больших целых чисел, чтобы обрабатывать все различные тестовые случаи.

Это только для общего случая, который вы можете использовать....

Это объясняется в Документация JavaScript:

Согласно стандарту ECMAScript, существует только один числовой тип: значение 64-битного двоичного формата двойной точности IEEE 754 в двоичном формате (числа между -(253-1) и 253-1). Для целых чисел не существует определенного типа.

Страница в Википедии о формат с плавающей запятой двойной точности объясняет:

Между 252= 4,503,599,627,370,496 и 253= 9,007,199,254,740,992 представимые числа - это в точности целые числа.Для следующего диапазона, начиная с 253 Для 254, все умножается на 2, таким образом, представимые числа являются четными и т.д.

(Все целые числа, меньшие 252 представлены точно.)

1234567890123456789 и 1234567890123456799 больше, чем 260= 1152921504606846976.При такой величине только около 1% целых чисел хранятся в точности с использованием формата с плавающей запятой двойной точности.

Эти два файла не могут быть сохранены в точности.Они оба округлены до 1234567890123456800.


Тот самый Документация JavaScript также объясняется, как определить, точно ли сохранено целое число:

[...] и начиная с ECMAScript 6, вы также можете проверить, находится ли число в диапазоне чисел с плавающей запятой двойной точности, используя Number.isSafeInteger() а также Number.MAX_SAFE_INTEGER и Number.MIN_SAFE_INTEGER.За пределами этого диапазона целые числа в JavaScript больше не безопасны и будут аппроксимацией значения с плавающей запятой двойной точности.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top