Что такое высочайшее целое значение JavaScript, число которого может идти без потери точности?

Определяется ли это языком? Есть ли определенный максимум? Разница в разных браузерах?

Ответ 1

+ / - 9007199254740991

ECMA Раздел 8.5 - Номера

Обратите внимание, что все положительные и отрицательные целые числа, величина которых не превышает 2 53 представимы в числовом типе (действительно, целое число 0 имеет два представления, +0 и -0).

Это 64-битные значения с плавающей запятой, наибольшее точное целое значение составляет 2 53 -1 или 9007199254740991. В ES6 это определяется как Number.MAX_SAFE_INTEGER.

Обратите внимание, что побитовые операторы и операторы сдвига работают с 32-разрядными целыми числами, поэтому в этом случае максимальное безопасное целое число равно 2 31 -1 или 2147483647.


Проверьте это!
var x = 9007199254740992;
var y = -x;
x == x + 1; // true !
y == y - 1; // also true !
// Arithmetic operators work, but bitwise/shifts only operate on int32:
x / 2;      // 4503599627370496
x >> 1;     // 0
x | 1;      // 1

Техническое примечание по теме номера 9007199254740992: Существует точное представление этого значения в IEEE-754, и вы можете присвоить и прочитать это значение из переменной, поэтому для очень тщательно выбранных приложений в области целых чисел, меньших или равных это значение, вы можете рассматривать это как максимальное значение.

В общем случае вы должны рассматривать это значение IEEE-754 как неточное, поскольку неясно, кодирует ли оно логическое значение 9007199254740992 или 9007199254740993.

Ответ 2

> = ES6:

Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;

<= ES5

Из ссылки:

Number.MAX_VALUE;
Number.MIN_VALUE;

console.log('MIN_VALUE', Number.MIN_VALUE);
console.log('MAX_VALUE', Number.MAX_VALUE);

console.log('MIN_SAFE_INTEGER', Number.MIN_SAFE_INTEGER); //ES6
console.log('MAX_SAFE_INTEGER', Number.MAX_SAFE_INTEGER); //ES6

Ответ 3

Это 2 53 == 9 007 199 254 740 992. Это связано с тем, что Number хранится как плавающая точка в 52-битной мантиссе.

Минимальное значение равно -2 53.

Это вызывает некоторые забавные вещи.

Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true

И также может быть опасно:)

var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
    // infinite loop
}

Дальше: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html

Ответ 4

В JavaScript есть номер с именем Infinity.

Примеры:

(Infinity>100)
=> true

// Also worth noting
Infinity - 1 == Infinity
=> true

Math.pow(2,1024) === Infinity
=> true

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

Ответ 5

Ответ Джимми правильно представляет непрерывный спектр целочисленного JavaScript как -9007199254740992 9007199254740992 включительно (извините 9007199254740993, вы можете подумать, что вы 9007199254740993, но вы ошибаетесь!  Демонстрация ниже или в jsfiddle).

document.write(9007199254740993);

Ответ 6

Чтобы быть в безопасности

var MAX_INT = 4294967295;

Рассуждение

Я думал, что буду умным и найду значение, при котором x + 1 === x с более прагматичным подходом.

Моя машина может подсчитывать только 10 миллионов в секунду... поэтому я вернусь с окончательным ответом через 28.56 лет.

Если вы не можете долго ждать, я готов поспорить, что

  • Большинство ваших циклов не работают в течение 28,56 лет.
  • 9007199254740992 === Math.pow(2, 53) + 1 достаточно доказано
  • Вы должны придерживаться 4294967295, который Math.pow(2,32) - 1, чтобы избежать ожидаемых проблем с битовым переключением

Поиск x + 1 === x:

(function () {
  "use strict";

  var x = 0
    , start = new Date().valueOf()
    ;

  while (x + 1 != x) {
    if (!(x % 10000000)) {
      console.log(x);
    }

    x += 1
  }

  console.log(x, new Date().valueOf() - start);
}());

Ответ 7

ECMAScript 6:

Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;

Ответ 8

Короткий ответ: "Это зависит".

Если youre использует побитовые операторы где угодно (или если вы ссылаетесь на длину массива), диапазоны:

Без подписи: 0…(-1>>>0)

Подписан: (-(-1>>>1)-1)…(-1>>>1)

(Так получилось, что побитовые операторы и максимальная длина массива ограничены 32-битными целыми числами.)

Если вы не используете побитовые операторы или работаете с массивами:

Подписан: (-Math.pow(2,53))…(+Math.pow(2,53))

Эти ограничения налагаются внутренним представлением типа "Число", что в целом соответствует представлению с плавающей запятой с двойной точностью IEEE 754. (Заметим, что в отличие от типичных значащих целых чисел величина отрицательного предела совпадает с величиной положительного предела из-за характеристик внутреннего представления, которое фактически включает отрицательный 0!)

Ответ 9

Многие ответы ранее показывают true результат 9007199254740992 === 9007199254740992 + 1
проверить, что 9 007 199 254 740 991 является максимально безопасным целым числом.

Что если мы продолжим накопление:

input: 9007199254740992 + 1  output: 9007199254740992  // expected: 9007199254740993
input: 9007199254740992 + 2  output: 9007199254740994  // expected: 9007199254740994
input: 9007199254740992 + 3  output: 9007199254740996  // expected: 9007199254740995
input: 9007199254740992 + 4  output: 9007199254740996  // expected: 9007199254740996

Мы могли бы обнаружили, что среди чисел больше чем 9 007 199 254 740 992, только четные числа представимы.

Это вход, чтобы объяснить, как 64-битный двоичный формат двойной точности работает на этом. Давайте посмотрим, как 9 007 199 254 740 992 будет проходить (представляться) с использованием этого двоичного формата.

Сначала мы начнем с 4 503 599 627 370 496 с краткой версией формата:

  1 . 0000 ---- 0000  *  2^52            =>  1  0000 ---- 0000.  
     |-- 52 bits --|    |exponent part|        |-- 52 bits --|

На стороне перед стрелкой у нас есть битовое значение 1 и смежная точка радиуса, затем, умножая 2^52, мы вправо переместим точку радиуса 52 шага, и она идет до конца. Теперь мы получаем 4503599627370496 в двоичном виде.

Теперь мы начинаем накапливать 1 к этому значению, пока все биты не будут установлены в 1, что равно 9 007 199 254 740 991 в десятичном виде.

  1 . 0000 ---- 0000  *  2^52  =>  1  0000 ---- 0000.  
                       (+1)
  1 . 0000 ---- 0001  *  2^52  =>  1  0000 ---- 0001.  
                       (+1)
  1 . 0000 ---- 0010  *  2^52  =>  1  0000 ---- 0010.  
                       (+1)
                        . 
                        .
                        .
  1 . 1111 ---- 1111  *  2^52  =>  1  1111 ---- 1111. 

Теперь, поскольку в 64-битном двоичном формате двойной точности он строго выделяет 52 бита для дроби, больше нет битов для переноса для добавления еще 1, поэтому мы можем установить все биты обратно в 0 и манипулировать ими. экспонентная часть:

  |--> This bit is implicit and persistent.
  |        
  1 . 1111 ---- 1111  *  2^52      =>  1  1111 ---- 1111. 
     |-- 52 bits --|                     |-- 52 bits --|

                          (+1)
                                     (radix point has no way to go)
  1 . 0000 ---- 0000  *  2^52 * 2  =>  1  0000 ---- 0000. * 2  
     |-- 52 bits --|                     |-- 52 bits --|

  =>  1 . 0000 ---- 0000  *  2^53 
         |-- 52 bits --| 

Теперь мы получаем 9 007 199 254 740 992, и с числом, большим его, формат может быть в 2 раза больше дроби:

                            (consume 2^52 to move radix point to the end)
  1 . 0000 ---- 0001  *  2^53  =>  1 0000 ---- 0001.  *  2
     |-- 52 bits --|                |-- 52 bits --|

Таким образом, когда число становится больше, чем 9 007 199 254 740 992 * 2 = 18 014 398 509 481 984, может быть проведено только 4 раза дроби:

input: 18014398509481984 + 1  output: 18014398509481984  // expected: 18014398509481985
input: 18014398509481984 + 2  output: 18014398509481984  // expected: 18014398509481986
input: 18014398509481984 + 3  output: 18014398509481984  // expected: 18014398509481987
input: 18014398509481984 + 4  output: 18014398509481988  // expected: 18014398509481988

Как насчет числа между [ 2 251 799 813 685 248, 4 503 599 627 370 496)?

 1 . 0000 ---- 0001  *  2^51  =>  1 0000 ---- 000.1
     |-- 52 bits --|                |-- 52 bits  --|

Значение бита 1 после точки радиуса равно 2 ^ -1. (= 1/2, = 0,5) Таким образом, когда число меньше 4 503 599 627 370 496 (2 ^ 52), есть один бит, доступный для представления 1/2 раз целого числа:

input: 4503599627370495.5   output: 4503599627370495.5  
input: 4503599627370495.75  output: 4503599627370495.5  

Менее 2 251 799 813 685 248 (2 ^ 51)

input: 2251799813685246.75   output: 2251799813685246.8  // expected: 2251799813685246.75 
input: 2251799813685246.25   output: 2251799813685246.2  // expected: 2251799813685246.25 
input: 2251799813685246.5    output: 2251799813685246.5

// If the digits exceed 17, JavaScript round it to print it.
//, but the value is held correctly:

input: 2251799813685246.25.toString(2) 
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2) 
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)   
output: "111111111111111111111111111111111111111111111111110.11"

И каков доступный диапазон экспонентной части? формат выделяет для него 11 битов. Полный формат из Wiki: (для более подробной информации, пожалуйста, перейдите туда)

IEEE 754 Double Floating Point Format.svg

enter image description here

Таким образом, чтобы сделать экспоненту часть 2 ^ 52, нам точно нужно установить e = 1075.

Ответ 10

Другое может уже дать общий ответ, но я подумал, что было бы неплохо дать быстрый способ его определения:

for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);

Что дает мне 9007199254740992 менее чем за миллисекунду в Chrome 30.

Он проверит полномочия 2, чтобы найти, какой из них, когда "добавлен" 1, равен себе.

Ответ 11

Все, что вы хотите использовать для побитовых операций, должно быть между 0x80000000 (-2147483648 или -2 ^ 31) и 0x7fffffff (2147483647 или 2 ^ 31 - 1).

Консоль скажет вам, что 0x80000000 равно +2147483648, но 0x80000000 и 0x80000000 равно -2147483648.

Ответ 12

Try:

maxInt = -1 >>> 1

В Firefox 3.6 это 2 ^ 31 - 1.

Ответ 13

Я сделал простой тест с формулой X- (X + 1) = - 1, и наибольшее значение X, которое я могу получить для работы в Safari, Opera и Firefox (проверено на OS X), составляет 9e15. Вот код, который я использовал для тестирования:

javascript: alert(9e15-(9e15+1));

Ответ 14

Позвольте добраться до источников

Описание

Константа MAX_SAFE_INTEGER имеет значение 9007199254740991 (9 9007199254740991 199 254 9007199254740991 991 или ~ 9 квадриллионов). Причиной этого числа является то, что JavaScript использует числа в формате с плавающей запятой двойной точности, как указано в IEEE 754, и может безопасно представлять только числа между -(2^53 - 1) и 2^53 - 1.

Безопасный в этом контексте относится к способности точно представлять целые числа и правильно их сравнивать. Например, Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 будет иметь значение true, что математически неверно. См. Number.isSafeInteger() для получения дополнительной информации.

Поскольку MAX_SAFE_INTEGER является статическим свойством Number, вы всегда используете его как Number.MAX_SAFE_INTEGER, а не как свойство созданного вами объекта Number.

Совместимость браузера

enter image description here

Ответ 15

В встроенном javascript Google Chrome вы можете перейти к приблизительно 2 ^ 1024, прежде чем число будет называться бесконечно.

Ответ 16

Я пишу это так:

var max_int = 0x20000000000000;
var min_int = -0x20000000000000;
(max_int + 1) === 0x20000000000000;  //true
(max_int - 1) < 0x20000000000000;    //true

То же самое для int32

var max_int32 =  0x80000000;
var min_int32 = -0x80000000;

Ответ 17

На момент написания JavaScript получает новый тип данных: BigInt. Это предложение TC39 на этапе 3. BigInt доступен в Chrome 67+, FireFox 67+ (требуется опция для его активации), Opera 54 и Node 10.4.0. Это происходит в Safari и др.... Он вводит числовые литералы с суффиксом "n" и допускает произвольную точность:

var a = 123456789012345678901012345678901n;

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

Ответ 18

Scato wrotes:

все, что вы хотите использовать для побитовых операций, должно быть между 0x80000000 (-2147483648 или -2 ^ 31) и 0x7fffffff (2147483647 или 2 ^ 31 - 1).

консоль скажет вам, что 0x80000000 равен +2147483648, но 0x80000000 и 0x80000000 равно -2147483648

Hex-Decimals - неподписанные положительные значения, поэтому 0x80000000 = 2147483648 - это математически корректно. Если вы хотите сделать это знаковым значением, вам нужно сдвинуть вправо: 0x80000000 → 0 = -2147483648. Вы можете написать 1 < 31 тоже.

Ответ 19

Number.MAX_VALUE представляет максимальное числовое значение, представленное в JavaScript.

Поскольку никто, кажется, так не сказал, в двигателе v8 существует разница в поведении для числа 31 bits и числа выше этого.

Если у вас есть 32 bits, вы можете использовать первый бит, чтобы сообщить движку javascript, какой тип данных и какие оставшиеся биты содержат фактические данные. То, что делает V8 как небольшая оптимизация для 31 bis numbers (или используется, мои источники довольно датированы). У вас последний 31 bits - это числовое значение, а затем первый бит, указывающий движку, если это число или ссылка на объект.

Однако, если вы используете номер выше 31 bits, тогда данные не будут вписываться, номер будет помещен в 64 бита в два раза, а оптимизация там не будет.

Нижняя строка в видео ниже:

предпочитают числовые значения, которые могут быть представлены как 31 бит.. целые числа.

Ответ 20

В основном javascript не поддерживает долго.
поэтому для нормальных значений, которые могут представлять менее 32 бит, он будет использовать контейнер типа int. для целочисленных значений, превышающих 32 бит, его использование удваивается. При двойном представлении целая часть составляет 53 бит, а остальное - мантисса (для сохранения информации с плавающей точкой).
поэтому вы можете использовать 2^53 - 1, значение которого 9007199254740991
вы можете получить доступ к значению, которое будет использоваться в вашем коде, Number.MAX_SAFE_INTEGER

Ответ 22

Когда число больше 2 до степени 53, т.е.

Math.pow(2, 53)

JavaScript знает это как большое целое число. Затем javascript сохраняет их как "bigint", поэтому сравнение с 'bigint'==='bigint' становится истинным.

Более безопасный способ хранить их значения в самом объекте Math.

const bigInt1 = Math.pow(2, 55)
const bigInt2 = Math.pow(2, 66)
console.log(bigInt1 === bigInt2) // false

Ответ 23

Node.js и Google Chrome, похоже, используют 1024-битные значения с плавающей запятой, поэтому:

Number.MAX_VALUE = 1.7976931348623157e+308

Ответ 24

У Firefox 3, похоже, нет проблем с огромными числами.

1e + 200 * 1e + 100 рассчитает штраф до 1e + 300.

У Safari, похоже, нет проблем с этим. (Для записи это на Mac, если кто-то другой решит проверить это.)

Если я потерял свой мозг в это время суток, это намного больше, чем 64-битное целое число.