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

Это определяется языком? Есть ли определенный максимум? В разных браузерах он разный?

Вам не нужно зависеть от ограничений JS с такими библиотеками, как github.com/MikeMcl/big.js, см., Например, здесь для проверки надежности

Dmitri Zaitsev 18.05.2016 07:26

какое наибольшее целое значение можно использовать с big.js?

George 26.03.2018 23:41

@George Вот API big.js: mikemcl.github.io/big.js/#dp

simhumileco 18.07.2018 12:35

Вопрос не имеет смысла. Что означает, что число «переходит» к целому значению? Если вы просто хотите спросить, какое наибольшее целое число вы можете представить в JS, самое высокое (конечное) число само по себе является целым числом.

Veky 26.10.2018 06:04

@DmitriZaitsev Нам больше не нужно зависеть от внешних библиотек (по крайней мере, в некоторых браузерах). 1n << 10000n - это действительно очень большое целое число, без потери точности, без каких-либо зависимостей (и, разумеется, даже близко не к пределу).

Amadan 06.01.2020 12:12

@Amadan Откуда здесь взялся 1n << 10000n?

Dmitri Zaitsev 08.01.2020 09:09

@DmitriZaitsev Просто случайный пример большого числа.

Amadan 08.01.2020 10:10

@Amadan Так как это случайное число может устранить необходимость во внешних библиотеках?

Dmitri Zaitsev 08.01.2020 14:21

@DmitriZaitsev Обратите внимание на суффикс n. Класс BigInt является частью проекта спецификации ES2020, уже реализованного в большинстве браузеров; вы можете попытаться оценить это, например, Chrome или Firefox без внешних библиотек и 3011-значный BigInt.

Amadan 08.01.2020 14:41

@Amadan Это только для целых чисел. Например. как точно добавить .1+.2?

Dmitri Zaitsev 08.01.2020 15:00

@DmitriZaitsev: Да, это только для целых чисел. Это вопрос о целых числах.

Amadan 08.01.2020 15:01
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1 007
11
546 790
21
Перейти к ответу Данный вопрос помечен как решенный

Ответы 21

> = ES6:

Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;

<= ES5

Из ссылка:

Number.MAX_VALUE;
Number.MIN_VALUE;

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

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

Я отредактировал вопрос, чтобы он был немного более точным в отношении максимальных значений Integer, а не только максимального значения Number. Извините за путаницу, здесь.

TALlama 21.11.2008 02:21

Гарантируется ли то, что возвращаемый результат будет одинаковым во всех браузерах?

Pacerier 21.09.2013 23:05

Обратите внимание, что Number.MIN_VALUE - это наименьшее возможное число положительный. Значение наименее (т.е. меньше, чем что-либо еще), вероятно, -Number.MAX_VALUE.

Michael Scheper 11.06.2014 03:19

Это максимальное значение с плавающей запятой. Речь идет о наивысшем целочисленном значении. И хотя Number.MAX_VALUE является целым числом, вы не можете пройти мимо 2^53 без потери точности.

Teepeemm 23.07.2014 02:01

@Teepeemm Это ответ почти шестилетней давности на вопрос почти шестилетней давности, поэтому любопытно, что вы позаботились о том, чтобы точнее стрелять по нему сейчас. Но если вы захотите посмотреть историю редактирования, вы увидите, что в исходном вопросе не были указаны целые числа stackoverflow.com/posts/307179/revisions, не говоря уже о комментарии OP, всего в 4 комментариях, где он упоминает о внесении этого редактирования / уточнения.

Peter Bailey 23.07.2014 02:08

ES6 представляет Number.MIN_SAFE_INTEGER и Number.MAX_SAFE_INTEGER

superlukas 31.08.2014 19:23

Итак, в этом случае, должны ли мы проголосовать против ответа, потому что он неверен для обновленного вопроса, или оставить его, потому что Питер Бейли был прав в то время, когда на него был дан ответ?

rocketsarefast 27.05.2015 19:28

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

Jules 22.02.2018 18:04

@rocketsarefast Я обновил текст ответа, включив в него информацию о ES6, но вы можете голосовать, как хотите. Я думаю, что здесь достаточно информации и разговоров о том, что голосование на данном этапе за такой старый вопрос / ответ в основном похоже на запрет.

Peter Bailey 01.03.2018 22:14

Этот ответ в его нынешнем виде неверен, потому что он подразумевает, что MAX_SAFE_INTEGER и MAX_VALUE оба отвечают на вопрос, и что разница только в том, какие версии ES поддерживают их. Фактически только MAX_SAFE_INTEGER правильно отвечает на вопрос в его нынешнем виде, и только MAX_VALUE ответил на вопрос в том виде, в котором он был первоначально опубликован. MIN_SAFE_INTEGER и MIN_VALUE не имеют отношения к точному вопросу.

Daira Hopwood 17.10.2020 15:23
Ответ принят как подходящий

В JavaScript есть два числовых типа: Number и BigInt.

Наиболее часто используемый числовой тип, Number, представляет собой 64-битное число IEEE 754 с плавающей запятой.

Наибольшее точное целое значение этого типа - Number.MAX_SAFE_INTEGER, что составляет:

  • 253-1, или
  • +/- 9 007 199 254 740 991, или
  • девять квадриллионов семь триллионов сто девяносто девять миллиардов двести пятьдесят четыре миллиона семьсот сорок тысяч девятьсот девяносто один

Для сравнения: один квадриллион байтов - это петабайт (или тысяча терабайт).

«Безопасный» в этом контексте относится к способности точно представлять целые числа и правильно их сравнивать.

Из спецификации:

Note that all the positive and negative integers whose magnitude is no greater than 253 are representable in the Number type (indeed, the integer 0 has two representations, +0 and -0).

Чтобы безопасно использовать целые числа больше этого, вам нужно использовать BigInt, у которого нет верхней границы.

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

const log = console.info
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !

// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2)      // 4503599627370496
log(x >> 1)     // 0
log(x | 1)      // 1

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

В общем случае вы должны рассматривать это значение IEEE-754 как неточное, потому что неясно, кодирует ли оно логическое значение 9,007,199,254,740,992 или 9,007,199,254,740,993.

Это кажется правильным, но есть ли место, где это определено, например MAX_INT C или Java Integer.MAX_VALUE?

TALlama 21.11.2008 02:35

согласно стандарту IEEE_754, 64-битная с плавающей запятой использует 53 бита для мантиссы. Что касается константы javascript, мне ничего не известно.

Jimmy 21.11.2008 21:14
4294967295 === Math.pow(2,32) - 1;
coolaj86 24.08.2011 00:15

Итак, какое наименьшее и наибольшее целое число мы можем использовать для обеспечения точной точности?

Pacerier 15.10.2011 20:21

для простых операций в первой части моего ответа указано 2^53. Я отредактировал, чтобы сделать ответ более ясным

Jimmy 15.10.2011 22:56

Возможно, стоит отметить, что в javascript нет фактического (int). Каждый экземпляр Number равен (float) или NaN.

Beetroot-Beetroot 31.08.2012 17:09

@ Свекла-Свекла или +/- Бесконечность

skeggse 01.12.2012 10:41

@ LucioM.Tato Вопрос конкретно требует "без потери точности" Number.MAX_VALUE - это "наибольшее значение, период", но, например, Number.MAX_VALUE - 1 не является допустимым значением.

Jimmy 28.05.2013 21:15

Каждый экземпляр Number - это (float) <stop here> "или NaN". ... «Или +/- бесконечность»: избыточный, IEEE-754 (с плавающей запятой) кодирует NaN и +/- бесконечность как часть формата. Также -0

MickLH 26.11.2013 12:57

@TALlama В ES6 для этого будет константа: Number.MAX_SAFE_INTEGER (уже установлена ​​в Chrome с включенным экспериментальным JS). Пока этот ответ хорош.

rvighne 17.03.2014 03:57

9007199254740992 на самом деле не является максимальным значением, последний бит здесь уже предполагается равным нулю, и поэтому вы потеряли 1 бит точности. Настоящий номер сейфа - 9007199254740991 (Number.MAX_SAFE_INTEGER).

Willem D'Haeseleer 21.08.2014 21:59

Между прочим, это число читается как: девять квадриллионов, семь триллионов, сто девяносто девять миллиардов, двести пятьдесят четыре миллиона, семьсот сорок тысяч, девятьсот девяносто один.

K Lee 13.03.2015 19:11

Кто-нибудь, объясните мне одну вещь. "Свойство MAX_VALUE имеет значение приблизительно 1.79E + 308 (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…‌). 1.79E + 308 - очень большое число, которое намного больше 2 ^ 53. Что означает Number.MAX_VALUE?

Evgeni Nabokov 24.03.2016 15:49

@EvgeniNabokov: Number.MAX_VALUE - это наибольшее значение, представленное 64-битным числом с плавающей запятой. Однако 64-битное число с плавающей запятой не может представлять все целые числа меньше 1.79E + 308 (как вы, вероятно, знаете, 64-битные могут представлять только 2 ^ 64 = 1.84E + 19 уникальных значений). Number.MAX_SAFE_VALUE или 9007199254740991 имеет свойство, заключающееся в том, что каждое положительное целое число <= 9007199254740991 точно может быть представлено 64-битным числом с плавающей запятой без потери точности. Вы можете видеть в моем фрагменте кода в ответе, что для значений x больше 9007199254740991 у вас может быть x == x + 1, что означает, что мы теряем точность.

Jimmy 24.03.2016 22:12

+1 за указание ограничений побитовых операторов !! Это полностью ускользает от меня, почему они решили использовать там 32-битную версию, поскольку она, очевидно, использует 64 для Number.

Ciprian Tomoiagă 10.03.2017 16:02

Итак, в миллисекундах UNIX это будет 12 октября 287396 года.

Kyle Delaney 27.06.2017 22:54

Особый случай - >>> определяется на uint32_t, а не на int32_t.

tsh 11.07.2017 06:48

@CiprianTomoiaga: Потому что 80386 был 32-битным процессором и не мог выполнять эти операции на 64-битном. А 80387 не имеет сменных операций. Пожалуйста, помните, что JS немного появился ...

Bodo Thiesen 24.08.2017 00:52

@BodoThiesen: Было ли когда-нибудь время, когда расширение побитовых операторов до 53 бит имело какое-либо значимое отрицательное влияние на производительность Javascript? В первые дни Javascript, когда 32-разрядные процессоры правили, производительность больше зависела от скорости интерпретатора и символьного поиска, чем от чего-либо, связанного с реальными числовыми операциями.

supercat 12.06.2018 22:29

Почему он 53-битный, если в документе говорится, что для хранения дроби 52 бита? Думаю, стоит упомянуть причину этого (по крайней мере, я не был достаточно умен, чтобы понять это сам), эта статья объясняет это в разделе «Примеры хранения целых чисел».

Marty ZHANG 21.06.2018 15:45

@supercat, я не сказал, я считаю, что это "хорошая" причина, я просто сказал, я верю, это БЫЛО причиной. И люди иногда стремятся оптимизировать не в тех местах. В любом случае: выполнение сдвига двойного значения создает необходимость либо преобразовать его в целое число и обратно, либо сильно округлить до и после сдвига. И да: выполнение 64-битного сдвига будет всего на одну инструкцию больше, чем выполнение 32-битного сдвига.

Bodo Thiesen 06.07.2018 18:03

@ T.J.Crowder - это просто другое определение «потери точности», и я думаю, что его использовать в качестве общего принципа более небезопасно. Представление IEEE-754 для значения 9007199254740992 такое же, как представление для значения 9007199254740993, поэтому, если у вас когда-либо был этот битовый шаблон, вы должны рассматривать его как неточное значение, поскольку вы не можете быть уверены, какое из двух значений оно средства.

Jimmy 29.09.2018 20:11

@ Джимми - Это все немного произвольно. :-) Но мне нравятся ваши рассуждения, хотя я спорю с «Представление IEEE-754 для значения 9007199254740992 такое же, как представление для значения 9007199254740993 ...». Для 9007199254740993 вообще нет никакого представления. Дело не в том, что это то же самое, что и 9007199254740992; нет ни одного. Таким образом, все, что пытается использовать это значение, должно снизиться до 9007199254740992 или до 9007199254740994. (продолжение)

T.J. Crowder 29.09.2018 20:16
(продолжение) Но отдельно, в поддержку вашего определения: 9007199254740991 - это последнее значение, для которого есть бит для места 1; начиная с 9007199254740992 младший бит - это 2 место. Таким образом, потеря точности. Так что да, можно по-разному смотреть на это, но мне нравится ваша точка зрения. :-) Может быть, сложить часть этого в ответ? Поскольку 9007199254740992 проводится точно ...
T.J. Crowder 29.09.2018 20:17

Благодарим за замечание о «побитовых операторах и операторах сдвига, работающих с 32-битными целыми числами». Только что заметил 1073741824 * 2 - 2147483648, но 1073741824 << 1 - -2147483648

Galaxy 09.09.2019 01:25

Как рассчитать максимальное число с учетом определенного количества десятичных знаков?

Dominic 16.10.2020 08:53

@Dominic Не существует такого количества десятичных знаков X> 0, чтобы все десятичные числа с такой точностью были представлены. например, десятичное число 0,1 не имеет точного представления в двоичном формате и не может быть точно представлено числами с плавающей запятой.

Jimmy 17.10.2020 01:44

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

1e + 200 * 1e + 100 рассчитывается как 1e + 300.

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

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

это не 64-битное целое число, это 64-битное число с плавающей запятой, из которых 52/53 бита являются целой частью. поэтому он будет обрабатывать до 1e300, но не с точной точностью.

Jimmy 21.11.2008 21:11

Джимми прав. Попробуйте это в своем браузере или в командной строке JS: 100000000000000010 - 1 => 100000000000000020

Ryan 08.10.2011 01:54

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

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

Обратите внимание, что 9e15 = 2 ^ 53 (см. Ответ @ Jimmy).

Wedge 21.11.2008 03:39

9e15 = 9000000000000000. 2 ^ 53 = 9007199254740992. Следовательно, чтобы быть педантичным, 9e15 только приблизительно равно 2 ^ 53 (с двумя значащими цифрами).

devios1 20.09.2012 02:24

@chaiguy В 9000000000000000 стоит 1 значащая цифра. в `9007199254740992` 15 значащих цифр.

Royi Namir 13.11.2013 10:36

@RoyiNamir Не хочу начинать здесь бессмысленную аргументацию, но 9000000000000000 имеет 16 значащих цифр. Если вы хотите только 1, это должно быть записано как 9x10 ^ 15.

devios1 13.11.2013 22:01

@chaiguy Нет. 9000000000000000 как есть - есть 1 SF. где 90*10^14 имеет 2. (sigfigscalculator.appspot.com) & mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (нижняя часть)

Royi Namir 13.11.2013 22:17

Пытаться:

maxInt = -1 >>> 1

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

@danorton: Я не уверен, что вы понимаете, что делаете. ^ означает возведен к власти. В консоли javascript ^ - это XOR, не повышенный до

kumarharsh 24.12.2013 15:09

@Kumar, я не понимаю, что вы имеете в виду или какое другое значение «^» имеет отношение к этому вопросу о JavaScript.

danorton 25.12.2013 18:42

откройте консоль Chrome / Firefox. Введите 5 ^ 2. В двоичном формате 5 - это 101, а 2 - это 010. Теперь, если вы выполните побитовое XOR, вы получите 5(101) ^ 2(010) = 7(111)ПРОЧИТАЙТЕ ЭТО, ЕСЛИ ВЫ ЗАБОТАЕТЕ. Здесь обсуждается Math.pow(), а не оператор ^.

kumarharsh 25.12.2013 19:22

Опять же, я совсем не запутался. Я прокомментировал и проголосовал против того, что такое написано. Если имеется в виду Math.pow (), то это и должно быть написано. В ответе на вопрос о JavaScript неуместно использовать синтаксис другого языка. Еще более неприемлемо использовать синтаксис, допустимый в JavaScript, но с интерпретацией в JavaScript, которая имеет значение, отличное от предполагаемого.

danorton 31.12.2013 22:56

2 ^ 31 - это то, как в английском языке пишут два в тридцать первой степени. Это не в блоке кода. Вы бы пожаловались на кого-то, использующего; в ответ, потому что это символ с другим значением в Javascript?

lmm 05.03.2014 17:55

Даже если один должен записывает 2³¹, а не 2 ^ 31 в виде обычного текста, обычно это делается, потому что большинство раскладок клавиатуры не имеют этих символов по умолчанию. По крайней мере, у меня не было проблем с пониманием того, что имел в виду этот ответ.

Jocke 03.06.2015 00:07

Я собирался сказать: ^), но это заставило меня понять, что это не более чем отвратительная синтаксическая ошибка

Gershy 13.09.2019 17:42

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

Минимальное значение - -253.

Это заставляет происходить забавные вещи

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
}

Further reading: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html

хотя никто никогда не достигнет конца этого цикла for в разумные сроки, вы можете сказать i += 1000000000

ninjagecko 08.07.2015 23:18

@ninjagecko, он начинает с MAX_INT, так что конец прямо здесь. Также использование i + = 1000000000 не сделает его бесконечным циклом. Попробуй это.

Ted Bigham 05.01.2016 03:52

@TedBigham: Ой, слишком быстро был готов к этому. Спасибо, что исправили меня дважды.

ninjagecko 05.01.2016 11:34

См. Аргумент Джимми для 9,007,199,254,740,991 вместо 9,007,199,254,740,992 здесь. Это, в сочетании с моим продолжением, кажется убедительным.

T.J. Crowder 29.09.2018 20:19

Короткий ответ: «это зависит от обстоятельств».

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

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

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

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

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

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

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

Это ответ, на который я хотел наткнуться, о том, как преобразовать X в 32-битное целое число или целое число без знака. Проголосовал за ваш ответ.

Charlie Affumigato 24.11.2013 06:51

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

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.info(x);
    }

    x += 1
  }

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

Вы не можете просто запустить его с 2 ^ 53-2, чтобы проверить? (да, вы можете, я только что попробовал, даже с -3 на всякий случай: var x = Math.pow (2,53) -3; while (x! = x + 1) x ++;) -> 9007199254740991

MickLH 18.11.2013 03:14

Хороший ответ! Более того, я знаю, что значение установлено, но почему бы не использовать двоичный поиск для его поиска?

higuaro 03.03.2014 22:22

Что в этом интересного? Кроме того, @ Briguy37 меня опередил: stackoverflow.com/a/11639621/151312

coolaj86 04.03.2014 23:04

обратите внимание, что этот «безопасный» MAX_INT, основанный на 32 битах, не будет работать при сравнении со значениями даты. 4294967295 это так вчера!

Jerry 21.05.2014 02:08

- 1; Меня это просто сбивало с толку. Иногда мне нравятся юмористические ответы, но я думаю, что вся эта тема достаточно сложна, особенно с учетом того, что некоторые читатели могут не знать, что целые числа хранятся в JavaScript как числа с плавающей запятой, или не понимают неточности с плавающей запятой, что добавляет "забавный" ответ на страницу смешение правдивых утверждений и хороших советов с глупостью - вредный ход. Кроме того, возможно, у меня просто плохое чувство юмора, но мне это не показалось смешным.

Mark Amery 26.12.2014 20:45

Кроме того, я до сих пор совершенно не уверен, каковы «ожидаемые проблемы со сдвигом битов».

Mark Amery 26.12.2014 20:48

Ответ «На всякий случай: var MAX_INT = 4294967295;» не юмористический. Если вы не выполняете сдвиг битов, не беспокойтесь об этом (если вам не нужен int больше 4294967295, и в этом случае вам, вероятно, следует сохранить его как строку и использовать библиотеку bigint).

coolaj86 27.12.2014 22:43

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

В JavaScript есть номер под названием Infinity.

Примеры:

(Infinity>100)
=> true

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

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

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

Что-то мне подсказывает, что бесконечность не считается целым числом. :)

devios1 20.09.2012 02:20

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

djjeck 24.10.2012 01:30

Обратите внимание, что Infinity - 1 === Infinity

H.Wolper 18.10.2013 13:22

также (Infinity <100) => false и Math.pow (2,1024) === Infinity

Sijav 30.10.2013 16:12

Math.pow (2,1024) === Бесконечность потрясающая. собираюсь добавить это.

BananaNeil 31.10.2013 00:22

Также ничего не стоит, что он также обрабатывает отрицательную бесконечность. Итак, 1 - Infinity === -Infinity

dmccabe 06.11.2014 00:51

в математике бесконечность - это не число, это понятие

user2006656 25.09.2016 00:11

Максимальное значение: Math.pow (2,1023) * 1,99999999999999998

Laxmikant Dange 08.03.2017 11:00

@ devios1 На самом деле это целое число, оно равно Infinity - 1 + 1.

Andrew 11.06.2020 01:17

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

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

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

console.info(9007199254740993);

Однако нет ответа, который находит / доказывает это программно (кроме одного CoolAJ86, упомянутого в его ответ, который закончится через 28,56 лет;), так что вот немного более эффективный способ сделать это (если быть точным, он более эффективен около 28,559999999968312 лет :), вместе с тестовая рабочий пример:

/**
 * Checks if adding/subtracting one to/from a number yields the correct result.
 *
 * @param number The number to test
 * @return true if you can add/subtract 1, false otherwise.
 */
var canAddSubtractOneFromNumber = function(number) {
    var numMinusOne = number - 1;
    var numPlusOne = number + 1;
    
    return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}

//Find the highest number
var highestNumber = 3; //Start with an integer 1 or higher

//Get a number higher than the valid integer range
while (canAddSubtractOneFromNumber(highestNumber)) {
    highestNumber *= 2;
}

//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
    while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) {
        highestNumber = highestNumber - numToSubtract;
    }
    
    numToSubtract /= 2;
}        

//And there was much rejoicing.  Yay.    
console.info('HighestNumber = ' + highestNumber);

@ CoolAJ86: Лол, я с нетерпением жду 15 марта 2040 года. Если наши цифры совпадают, мы должны устроить вечеринку :)

Briguy37 13.02.2013 02:15

var x = Math.pow (2,53) -3; в то время как (x! = x + 1) x ++; -> 9007199254740991

MickLH 18.11.2013 03:18

@MickLH: я получаю 9007199254740992 с этот код. Какой движок JavaScript вы используете для тестирования?

Briguy37 18.11.2013 19:52

Вы получаете 9007199254740992 с вашим собственным кодом, я использовал не окончательное значение x, а окончательную оценку x ++ по параноидальным причинам. Кстати, Google Chrome.

MickLH 18.11.2013 22:00

@MickLH: оценка x++ дает вам значение x до, когда произошло приращение, так что, вероятно, это объясняет несоответствие. Если вы хотите, чтобы выражение оценивалось так же, как окончательное значение x, вы должны изменить его на ++x.

peterflynn 24.11.2013 11:51

Спасибо, но я знаю семантику постинкремента и использовал ее «окончательную оценку» (в отличие от окончательного значения x), потому что она предоставляет число, где (x! = X + 1), также известное как «последнее число где +1 работает "в отличие от" первого числа, где он не работает "

MickLH 25.11.2013 09:26

@MickLH: "last number where +1 works" == "max number w/out losing precision" - 1

Briguy37 25.11.2013 20:41

1. на вопрос есть принятый ответ, так что ваше отношение к чему-то я не говорил либо неверно, либо бесполезно объективно. 2. Цель моего комментария - показать, что большой алгоритм, который вы написали, - довольно бесполезная трата времени, добрый день, сэр. (Мне жаль, что вы так оскорбляетесь моим объяснением моей концепции с помощью очень похожего алгоритма, который также служит цели, которая действительно полезна для меня, также он вычисляет тот же X;))

MickLH 25.11.2013 21:39

@MickLH: Хорошо, я совершенно не понял, что вы пытались сказать. Я думал, что ваш первый алгоритм должен показать, что 9007199254740991 был правильным ответом. Напротив, это должно было показать, что моя - бесполезная трата времени. Я рад, что мы это прояснили ...

Briguy37 26.11.2013 00:52

Но люблю тебя, братан, не делай этого, как я злая задница, которая не ценит эту эффективность

MickLH 26.11.2013 12:55

Не могли бы вы значительно ускорить это, начав с большого значения и проверяя только меньшие значения, когда вы теряете точность? Вместо добавления 1 за петлю, лол

Marie 20.07.2017 22:41

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

Number.MAX_VALUE = 1.7976931348623157e+308

-1: максимальное представимое (неточное целое) число может быть ~ 2 ^ 1024, но это не означает, что они отклоняются от стандарта IEEE-754 64-bit.

Roy Tinker 04.04.2013 01:44

MAX_INT? Вы имеете в виду MAX_VALUE?

Raul Guiu 29.05.2013 13:54

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

phuclv 04.08.2013 14:30

Или, что более важно, вы не можете надежно хранить int с таким длинным без потери точности. 2^53 упоминается как MAX_SAFE_INT, потому что выше этой точки значения становятся приблизительными, так же как и дроби.

IMSoP 16.06.2014 22:32

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

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

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

Он проверит степень двойки, чтобы определить, какая из них при «добавлении» 1 равна ему.

«Это может привести к сбою вашего приложения, - подумал.

Sapphire_Brick 14.11.2019 04:51

ECMAScript 6:

Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
Остерегатьсяэто (пока) не поддерживается всеми браузерами! Сегодня iOS (даже не хром), Safari и IE не нравятся.
cregox 07.05.2015 01:45

Пожалуйста, прочтите ответ внимательно, мы не используем реализацию Number.MAX_SAFE_INTEGER по умолчанию в ECMAScript 6, мы определяем ее как Math.pow (2, 53) -1

WaiKit Kung 08.05.2015 04:17

Я думал, это просто ссылка на то, как это реализовано в ECMA 6! : P Я думаю, что мой комментарий все еще в силе. Все зависит от контекста. ;)

cregox 08.05.2015 04:24

Насколько надежно рассчитать MAX_SAFE_INTEGER во всех браузерах, работая в обратном направлении? Стоит ли вместо этого двигаться вперед? То есть Number.MAX_SAFE_INTEGER = 2 * (Math.pow (2, 52) - 1) + 1;

kjv 26.05.2015 21:45

Math.pow(2, 53)-1 - безопасная работа? Оно на единицу больше наибольшего безопасного целого числа.

ioquatix 13.03.2017 06:09

Да, это вычисление верное. Math.pow(2, 53) точно представим, а вычитание четко определено и точно.

Daira Hopwood 17.10.2020 15:26

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

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;

Скато пишет:

anything you want to use for bitwise operations must be between 0x80000000 (-2147483648 or -2^31) and 0x7fffffff (2147483647 or 2^31 - 1).

the console will tell you that 0x80000000 equals +2147483648, but 0x80000000 & 0x80000000 equals -2147483648

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

Многие более ранние ответы показали, что 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 и смежный точка счисления. При использовании экспоненты слева точка системы счисления перемещается на 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)

  1 . 0000 ---- 0000  *  2^52 * 2  =>  1  0000 ---- 0000. * 2  
     |-- 52 bits --|                     |-- 52 bits --|
                                      (By consuming the 2^52, radix
                                       point has no way to go, but
                                       there is still one 2 left in
                                       exponent part)
  =>  1 . 0000 ---- 0000  *  2^53 
         |-- 52 bits --| 

Теперь мы получаем 9 007 199 254 740 992, и для числа, большего, чем оно, формат может обрабатывать только приращения 2, потому что каждое приращение 1 в дробной части в конечном итоге умножается на левую 2 в экспоненциальной части. Вот почему 64-битный двоичный формат с двойной точностью не может содержать нечетные числа, когда число больше 9 007 199 254 740 992:

                            (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, может быть удержана только четырехкратная дробь:

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  --|

Значение 0,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
/**
   Please note that if you try this yourself and, say, log 
   these numbers to the console, they will get rounded. JavaScript
   rounds if the number of digits exceed 17. The value 
   is internally 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 бит.

От Википедия (подробнее там)

IEEE 754 Double Floating Point Format.svg

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

Переходим к источники

Описание

The MAX_SAFE_INTEGER constant has a value of 9007199254740991 (9,007,199,254,740,991 or ~9 quadrillion). The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 and can only safely represent numbers between -(2^53 - 1) and 2^53 - 1.

Safe in this context refers to the ability to represent integers exactly and to correctly compare them. For example, Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 will evaluate to true, which is mathematically incorrect. See Number.isSafeInteger() for more information.

Because MAX_SAFE_INTEGER is a static property of Number, you always use it as Number.MAX_SAFE_INTEGER, rather than as a property of a Number object you created.

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

В JavaScript числа представлены как 2^53 - 1.

тем не мение, Bitwise operation рассчитываются на 32 bits ( 4 bytes ), что означает, что если вы превысите 32-битные сдвиги, вы начнете терять биты.

Это важный момент. Вот почему я здесь гуглю максимальный размер int. Другие ответы предполагают 53 бита, поэтому я закодировал его, думая, что могу безопасно выполнять побитовую арифметику положительных значений до 52 бит. Но это не удалось после 31 бита. Спасибо @Marwen

JimbobTheSailor 08.03.2021 04:03

На момент написания JavaScript получает новый тип данных: BigInt. Это предложение TC39 в 4 этап, которое должно быть включено в EcmaScript 2020. BigInt доступен в Chrome 67+, FireFox 68+, Opera 54 и Node 10.4.0. Он реализуется в Safari и др ... Он вводит числовые литералы с суффиксом «n» и допускает произвольную точность:

var a = 123456789012345678901012345678901n;

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

И, очевидно, всегда будут ограничения точности из-за ограниченного объема памяти и затрат времени на выделение необходимой памяти и выполнение арифметических операций с такими большими числами.

Например, генерация числа из ста тысяч десятичных цифр займет заметную задержку до завершения:

console.info(BigInt("1".padEnd(100000,"0")) + 1n)

... но это работает.

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