Это определяется языком? Есть ли определенный максимум? В разных браузерах он разный?
какое наибольшее целое значение можно использовать с big.js?
@George Вот API big.js: mikemcl.github.io/big.js/#dp
Вопрос не имеет смысла. Что означает, что число «переходит» к целому значению? Если вы просто хотите спросить, какое наибольшее целое число вы можете представить в JS, самое высокое (конечное) число само по себе является целым числом.
@DmitriZaitsev Нам больше не нужно зависеть от внешних библиотек (по крайней мере, в некоторых браузерах). 1n << 10000n - это действительно очень большое целое число, без потери точности, без каких-либо зависимостей (и, разумеется, даже близко не к пределу).
@Amadan Откуда здесь взялся 1n << 10000n?
@DmitriZaitsev Просто случайный пример большого числа.
@Amadan Так как это случайное число может устранить необходимость во внешних библиотеках?
@DmitriZaitsev Обратите внимание на суффикс n. Класс BigInt является частью проекта спецификации ES2020, уже реализованного в большинстве браузеров; вы можете попытаться оценить это, например, Chrome или Firefox без внешних библиотек и 3011-значный BigInt.
@Amadan Это только для целых чисел. Например. как точно добавить .1+.2?
@DmitriZaitsev: Да, это только для целых чисел. Это вопрос о целых числах.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


> = 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. Извините за путаницу, здесь.
Гарантируется ли то, что возвращаемый результат будет одинаковым во всех браузерах?
Обратите внимание, что Number.MIN_VALUE - это наименьшее возможное число положительный. Значение наименее (т.е. меньше, чем что-либо еще), вероятно, -Number.MAX_VALUE.
Это максимальное значение с плавающей запятой. Речь идет о наивысшем целочисленном значении. И хотя Number.MAX_VALUE является целым числом, вы не можете пройти мимо 2^53 без потери точности.
@Teepeemm Это ответ почти шестилетней давности на вопрос почти шестилетней давности, поэтому любопытно, что вы позаботились о том, чтобы точнее стрелять по нему сейчас. Но если вы захотите посмотреть историю редактирования, вы увидите, что в исходном вопросе не были указаны целые числа stackoverflow.com/posts/307179/revisions, не говоря уже о комментарии OP, всего в 4 комментариях, где он упоминает о внесении этого редактирования / уточнения.
ES6 представляет Number.MIN_SAFE_INTEGER и Number.MAX_SAFE_INTEGER
Итак, в этом случае, должны ли мы проголосовать против ответа, потому что он неверен для обновленного вопроса, или оставить его, потому что Питер Бейли был прав в то время, когда на него был дан ответ?
@Pacerier - хороший вопрос, который был проигнорирован: ответ оказался да: все соответствующие реализации ECMAscript должны вести себя так, как если бы числа хранятся как числа с плавающей запятой двойной точности IEEE 754, поэтому все реализации должны давать одинаковые ответы для эти константы.
@rocketsarefast Я обновил текст ответа, включив в него информацию о ES6, но вы можете голосовать, как хотите. Я думаю, что здесь достаточно информации и разговоров о том, что голосование на данном этапе за такой старый вопрос / ответ в основном похоже на запрет.
Этот ответ в его нынешнем виде неверен, потому что он подразумевает, что MAX_SAFE_INTEGER и MAX_VALUE оба отвечают на вопрос, и что разница только в том, какие версии ES поддерживают их. Фактически только MAX_SAFE_INTEGER правильно отвечает на вопрос в его нынешнем виде, и только MAX_VALUE ответил на вопрос в том виде, в котором он был первоначально опубликован. MIN_SAFE_INTEGER и MIN_VALUE не имеют отношения к точному вопросу.
В JavaScript есть два числовых типа: Number и BigInt.
Наиболее часто используемый числовой тип, Number, представляет собой 64-битное число IEEE 754 с плавающей запятой.
Наибольшее точное целое значение этого типа - Number.MAX_SAFE_INTEGER, что составляет:
Для сравнения: один квадриллион байтов - это петабайт (или тысяча терабайт).
«Безопасный» в этом контексте относится к способности точно представлять целые числа и правильно их сравнивать.
Note that all the positive and negative integers whose magnitude is no greater than 253 are representable in the
Numbertype (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?
согласно стандарту IEEE_754, 64-битная с плавающей запятой использует 53 бита для мантиссы. Что касается константы javascript, мне ничего не известно.
4294967295 === Math.pow(2,32) - 1;Итак, какое наименьшее и наибольшее целое число мы можем использовать для обеспечения точной точности?
для простых операций в первой части моего ответа указано 2^53. Я отредактировал, чтобы сделать ответ более ясным
Возможно, стоит отметить, что в javascript нет фактического (int). Каждый экземпляр Number равен (float) или NaN.
@ Свекла-Свекла или +/- Бесконечность
@ LucioM.Tato Вопрос конкретно требует "без потери точности" Number.MAX_VALUE - это "наибольшее значение, период", но, например, Number.MAX_VALUE - 1 не является допустимым значением.
Каждый экземпляр Number - это (float) <stop here> "или NaN". ... «Или +/- бесконечность»: избыточный, IEEE-754 (с плавающей запятой) кодирует NaN и +/- бесконечность как часть формата. Также -0
@TALlama В ES6 для этого будет константа: Number.MAX_SAFE_INTEGER (уже установлена в Chrome с включенным экспериментальным JS). Пока этот ответ хорош.
9007199254740992 на самом деле не является максимальным значением, последний бит здесь уже предполагается равным нулю, и поэтому вы потеряли 1 бит точности. Настоящий номер сейфа - 9007199254740991 (Number.MAX_SAFE_INTEGER).
Между прочим, это число читается как: девять квадриллионов, семь триллионов, сто девяносто девять миллиардов, двести пятьдесят четыре миллиона, семьсот сорок тысяч, девятьсот девяносто один.
Кто-нибудь, объясните мне одну вещь. "Свойство MAX_VALUE имеет значение приблизительно 1.79E + 308 (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…). 1.79E + 308 - очень большое число, которое намного больше 2 ^ 53. Что означает Number.MAX_VALUE?
@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, что означает, что мы теряем точность.
+1 за указание ограничений побитовых операторов !! Это полностью ускользает от меня, почему они решили использовать там 32-битную версию, поскольку она, очевидно, использует 64 для Number.
Итак, в миллисекундах UNIX это будет 12 октября 287396 года.
Особый случай - >>> определяется на uint32_t, а не на int32_t.
@CiprianTomoiaga: Потому что 80386 был 32-битным процессором и не мог выполнять эти операции на 64-битном. А 80387 не имеет сменных операций. Пожалуйста, помните, что JS немного появился ...
@BodoThiesen: Было ли когда-нибудь время, когда расширение побитовых операторов до 53 бит имело какое-либо значимое отрицательное влияние на производительность Javascript? В первые дни Javascript, когда 32-разрядные процессоры правили, производительность больше зависела от скорости интерпретатора и символьного поиска, чем от чего-либо, связанного с реальными числовыми операциями.
Почему он 53-битный, если в документе говорится, что для хранения дроби 52 бита? Думаю, стоит упомянуть причину этого (по крайней мере, я не был достаточно умен, чтобы понять это сам), эта статья объясняет это в разделе «Примеры хранения целых чисел».
@supercat, я не сказал, я считаю, что это "хорошая" причина, я просто сказал, я верю, это БЫЛО причиной. И люди иногда стремятся оптимизировать не в тех местах. В любом случае: выполнение сдвига двойного значения создает необходимость либо преобразовать его в целое число и обратно, либо сильно округлить до и после сдвига. И да: выполнение 64-битного сдвига будет всего на одну инструкцию больше, чем выполнение 32-битного сдвига.
@ T.J.Crowder - это просто другое определение «потери точности», и я думаю, что его использовать в качестве общего принципа более небезопасно. Представление IEEE-754 для значения 9007199254740992 такое же, как представление для значения 9007199254740993, поэтому, если у вас когда-либо был этот битовый шаблон, вы должны рассматривать его как неточное значение, поскольку вы не можете быть уверены, какое из двух значений оно средства.
@ Джимми - Это все немного произвольно. :-) Но мне нравятся ваши рассуждения, хотя я спорю с «Представление IEEE-754 для значения 9007199254740992 такое же, как представление для значения 9007199254740993 ...». Для 9007199254740993 вообще нет никакого представления. Дело не в том, что это то же самое, что и 9007199254740992; нет ни одного. Таким образом, все, что пытается использовать это значение, должно снизиться до 9007199254740992 или до 9007199254740994. (продолжение)
Благодарим за замечание о «побитовых операторах и операторах сдвига, работающих с 32-битными целыми числами». Только что заметил 1073741824 * 2 - 2147483648, но 1073741824 << 1 - -2147483648
Как рассчитать максимальное число с учетом определенного количества десятичных знаков?
@Dominic Не существует такого количества десятичных знаков X> 0, чтобы все десятичные числа с такой точностью были представлены. например, десятичное число 0,1 не имеет точного представления в двоичном формате и не может быть точно представлено числами с плавающей запятой.
Firefox 3, похоже, не имеет проблем с огромными числами.
1e + 200 * 1e + 100 рассчитывается как 1e + 300.
У Safari, похоже, тоже нет проблем с этим. (Для записи, это на Mac, если кто-то еще решит это проверить.)
Если только я не потерял мозг в это время суток, это намного больше, чем 64-битное целое число.
это не 64-битное целое число, это 64-битное число с плавающей запятой, из которых 52/53 бита являются целой частью. поэтому он будет обрабатывать до 1e300, но не с точной точностью.
Джимми прав. Попробуйте это в своем браузере или в командной строке JS: 100000000000000010 - 1 => 100000000000000020
Я провел простой тест с формулой X- (X + 1) = - 1, и наибольшее значение X, которое я могу получить для работы в Safari, Opera и Firefox (проверено на OS X), составляет 9e15. Вот код, который я использовал для тестирования:
javascript: alert(9e15-(9e15+1));
Обратите внимание, что 9e15 = 2 ^ 53 (см. Ответ @ Jimmy).
9e15 = 9000000000000000. 2 ^ 53 = 9007199254740992. Следовательно, чтобы быть педантичным, 9e15 только приблизительно равно 2 ^ 53 (с двумя значащими цифрами).
@chaiguy В 9000000000000000 стоит 1 значащая цифра. в `9007199254740992` 15 значащих цифр.
@RoyiNamir Не хочу начинать здесь бессмысленную аргументацию, но 9000000000000000 имеет 16 значащих цифр. Если вы хотите только 1, это должно быть записано как 9x10 ^ 15.
@chaiguy Нет. 9000000000000000 как есть - есть 1 SF. где 90*10^14 имеет 2. (sigfigscalculator.appspot.com) & mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (нижняя часть)
Пытаться:
maxInt = -1 >>> 1
В Firefox 3.6 это 2 ^ 31-1.
@danorton: Я не уверен, что вы понимаете, что делаете. ^ означает возведен к власти. В консоли javascript ^ - это XOR, не повышенный до
@Kumar, я не понимаю, что вы имеете в виду или какое другое значение «^» имеет отношение к этому вопросу о JavaScript.
откройте консоль Chrome / Firefox. Введите 5 ^ 2. В двоичном формате 5 - это 101, а 2 - это 010. Теперь, если вы выполните побитовое XOR, вы получите 5(101) ^ 2(010) = 7(111)ПРОЧИТАЙТЕ ЭТО, ЕСЛИ ВЫ ЗАБОТАЕТЕ. Здесь обсуждается Math.pow(), а не оператор ^.
Опять же, я совсем не запутался. Я прокомментировал и проголосовал против того, что такое написано. Если имеется в виду Math.pow (), то это и должно быть написано. В ответе на вопрос о JavaScript неуместно использовать синтаксис другого языка. Еще более неприемлемо использовать синтаксис, допустимый в JavaScript, но с интерпретацией в JavaScript, которая имеет значение, отличное от предполагаемого.
2 ^ 31 - это то, как в английском языке пишут два в тридцать первой степени. Это не в блоке кода. Вы бы пожаловались на кого-то, использующего; в ответ, потому что это символ с другим значением в Javascript?
Даже если один должен записывает 2³¹, а не 2 ^ 31 в виде обычного текста, обычно это делается, потому что большинство раскладок клавиатуры не имеют этих символов по умолчанию. По крайней мере, у меня не было проблем с пониманием того, что имел в виду этот ответ.
Я собирался сказать: ^), но это заставило меня понять, что это не более чем отвратительная синтаксическая ошибка
Это 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, он начинает с MAX_INT, так что конец прямо здесь. Также использование i + = 1000000000 не сделает его бесконечным циклом. Попробуй это.
@TedBigham: Ой, слишком быстро был готов к этому. Спасибо, что исправили меня дважды.
См. Аргумент Джимми для 9,007,199,254,740,991 вместо 9,007,199,254,740,992 здесь. Это, в сочетании с моим продолжением, кажется убедительным.
Короткий ответ: «это зависит от обстоятельств».
Если вы где-то используете побитовые операторы (или если вы имеете в виду длину массива), диапазоны следующие:
Без подписи: 0…(-1>>>0)
Подпись: (-(-1>>>1)-1)…(-1>>>1)
(Так получилось, что побитовые операторы и максимальная длина массива ограничены 32-битными целыми числами.)
Если вы не используете побитовые операторы и не работаете с длинами массивов:
Подпись: (-Math.pow(2,53))…(+Math.pow(2,53))
Эти ограничения накладываются внутренним представлением типа «Число», которое обычно соответствует представлению с плавающей запятой двойной точности IEEE 754. (Обратите внимание, что в отличие от типичных целых чисел со знаком, величина отрицательного предела такая же, как величина положительного предела, из-за характеристик внутреннего представления, которое фактически включает отрицательный 0!)
Это ответ, на который я хотел наткнуться, о том, как преобразовать X в 32-битное целое число или целое число без знака. Проголосовал за ваш ответ.
var MAX_INT = 4294967295;
Я подумал, что проявлю смекалку и найду ценность x + 1 === x при более прагматичном подходе.
Моя машина может считать только 10 миллионов в секунду или около того ... поэтому я отправлю ответ с окончательным ответом через 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
Хороший ответ! Более того, я знаю, что значение установлено, но почему бы не использовать двоичный поиск для его поиска?
Что в этом интересного? Кроме того, @ Briguy37 меня опередил: stackoverflow.com/a/11639621/151312
обратите внимание, что этот «безопасный» MAX_INT, основанный на 32 битах, не будет работать при сравнении со значениями даты. 4294967295 это так вчера!
- 1; Меня это просто сбивало с толку. Иногда мне нравятся юмористические ответы, но я думаю, что вся эта тема достаточно сложна, особенно с учетом того, что некоторые читатели могут не знать, что целые числа хранятся в JavaScript как числа с плавающей запятой, или не понимают неточности с плавающей запятой, что добавляет "забавный" ответ на страницу смешение правдивых утверждений и хороших советов с глупостью - вредный ход. Кроме того, возможно, у меня просто плохое чувство юмора, но мне это не показалось смешным.
Кроме того, я до сих пор совершенно не уверен, каковы «ожидаемые проблемы со сдвигом битов».
Ответ «На всякий случай: var MAX_INT = 4294967295;» не юмористический. Если вы не выполняете сдвиг битов, не беспокойтесь об этом (если вам не нужен int больше 4294967295, и в этом случае вам, вероятно, следует сохранить его как строку и использовать библиотеку bigint).
Во встроенном javascript Google Chrome вы можете перейти примерно к 2 ^ 1024, прежде чем число будет называться бесконечным.
В JavaScript есть номер под названием Infinity.
Примеры:
(Infinity>100)
=> true
// Also worth noting
Infinity - 1 == Infinity
=> true
Math.pow(2,1024) === Infinity
=> true
Этого может быть достаточно для некоторых вопросов по этой теме.
Что-то мне подсказывает, что бесконечность не считается целым числом. :)
Но достаточно инициализировать переменную min, когда вы ищете минимальное значение.
Обратите внимание, что Infinity - 1 === Infinity
также (Infinity <100) => false и Math.pow (2,1024) === Infinity
Math.pow (2,1024) === Бесконечность потрясающая. собираюсь добавить это.
Также ничего не стоит, что он также обрабатывает отрицательную бесконечность. Итак, 1 - Infinity === -Infinity
в математике бесконечность - это не число, это понятие
Максимальное значение: Math.pow (2,1023) * 1,99999999999999998
@ devios1 На самом деле это целое число, оно равно Infinity - 1 + 1.
Все, что вы хотите использовать для побитовых операций, должно находиться в диапазоне от 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 года. Если наши цифры совпадают, мы должны устроить вечеринку :)
var x = Math.pow (2,53) -3; в то время как (x! = x + 1) x ++; -> 9007199254740991
@MickLH: я получаю 9007199254740992 с этот код. Какой движок JavaScript вы используете для тестирования?
Вы получаете 9007199254740992 с вашим собственным кодом, я использовал не окончательное значение x, а окончательную оценку x ++ по параноидальным причинам. Кстати, Google Chrome.
@MickLH: оценка x++ дает вам значение x до, когда произошло приращение, так что, вероятно, это объясняет несоответствие. Если вы хотите, чтобы выражение оценивалось так же, как окончательное значение x, вы должны изменить его на ++x.
Спасибо, но я знаю семантику постинкремента и использовал ее «окончательную оценку» (в отличие от окончательного значения x), потому что она предоставляет число, где (x! = X + 1), также известное как «последнее число где +1 работает "в отличие от" первого числа, где он не работает "
@MickLH: "last number where +1 works" == "max number w/out losing precision" - 1
1. на вопрос есть принятый ответ, так что ваше отношение к чему-то я не говорил либо неверно, либо бесполезно объективно. 2. Цель моего комментария - показать, что большой алгоритм, который вы написали, - довольно бесполезная трата времени, добрый день, сэр. (Мне жаль, что вы так оскорбляетесь моим объяснением моей концепции с помощью очень похожего алгоритма, который также служит цели, которая действительно полезна для меня, также он вычисляет тот же X;))
@MickLH: Хорошо, я совершенно не понял, что вы пытались сказать. Я думал, что ваш первый алгоритм должен показать, что 9007199254740991 был правильным ответом. Напротив, это должно было показать, что моя - бесполезная трата времени. Я рад, что мы это прояснили ...
Но люблю тебя, братан, не делай этого, как я злая задница, которая не ценит эту эффективность
Не могли бы вы значительно ускорить это, начав с большого значения и проверяя только меньшие значения, когда вы теряете точность? Вместо добавления 1 за петлю, лол
Node.js и Google Chrome, похоже, используют 1024-битные значения с плавающей запятой, поэтому:
Number.MAX_VALUE = 1.7976931348623157e+308
-1: максимальное представимое (неточное целое) число может быть ~ 2 ^ 1024, но это не означает, что они отклоняются от стандарта IEEE-754 64-bit.
MAX_INT? Вы имеете в виду MAX_VALUE?
это максимальное значение плавающая точка. Это не значит, что вы можете хранить int так долго
Или, что более важно, вы не можете надежно хранить int с таким длинным без потери точности. 2^53 упоминается как MAX_SAFE_INT, потому что выше этой точки значения становятся приблизительными, так же как и дроби.
Другой, возможно, уже дал общий ответ, но я подумал, что было бы неплохо дать быстрый способ его определения:
for (var x = 2; x + 1 !== x; x *= 2);
console.info(x);
Это дает мне 9007199254740992 менее чем за миллисекунду в Chrome 30.
Он проверит степень двойки, чтобы определить, какая из них при «добавлении» 1 равна ему.
«Это может привести к сбою вашего приложения, - подумал.
ECMAScript 6:
Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
Пожалуйста, прочтите ответ внимательно, мы не используем реализацию Number.MAX_SAFE_INTEGER по умолчанию в ECMAScript 6, мы определяем ее как Math.pow (2, 53) -1
Я думал, это просто ссылка на то, как это реализовано в ECMA 6! : P Я думаю, что мой комментарий все еще в силе. Все зависит от контекста. ;)
Насколько надежно рассчитать MAX_SAFE_INTEGER во всех браузерах, работая в обратном направлении? Стоит ли вместо этого двигаться вперед? То есть Number.MAX_SAFE_INTEGER = 2 * (Math.pow (2, 52) - 1) + 1;
Math.pow(2, 53)-1 - безопасная работа? Оно на единицу больше наибольшего безопасного целого числа.
Да, это вычисление верное. Math.pow(2, 53) точно представим, а вычитание четко определено и точно.
Я пишу это так:
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 бит.
От Википедия (подробнее там)
Таким образом, чтобы показатель степени был равен 2 ^ 52, нам точно нужно установить e = 1075.
The
MAX_SAFE_INTEGERconstant has a value of9007199254740991(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)and2^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 + 2will evaluate to true, which is mathematically incorrect. See Number.isSafeInteger() for more information.Because
MAX_SAFE_INTEGERis a static property of Number, you always use it asNumber.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
На момент написания 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)
... но это работает.
Вам не нужно зависеть от ограничений JS с такими библиотеками, как github.com/MikeMcl/big.js, см., Например, здесь для проверки надежности