Исходный алгоритм двоичного поиска в JDK использовал 32-разрядные целые числа и имел ошибку переполнения if (low + high) > INT_MAX
( http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html ) ,
Если мы переписали тот же алгоритм двоичного поиска с использованием (подписанных) 64-разрядных целых чисел, можем ли мы предположить, что low + high
он никогда не превысит INT64_MAX, поскольку физически невозможно иметь 10 ^ 18 байт памяти?
При использовании (подписанных) 64-битных целых чисел для представления физических величин , разумно ли предполагать, что переполнение не может произойти?
design
algorithms
Сики Лин
источник
источник
Ответы:
Короткий ответ: нет. Однако для некоторых приложений ваше предположение может быть правильным.
Предполагая, что подписанное целое число 2 ^ 63 с запятыми, добавленными для некоторой ясности, = 9,223,372,036,854,775,808. Так что примерно 9 * 10 ^ 18. 10 ^ 18 это «Exa».
Википедия говорит: «По состоянию на 2013 год, Всемирная паутина, по оценкам, достигла 4 зетабайтов. [12]», что составляет 4000 экзабайт. Таким образом, WWW примерно в 400 раз больше, чем 2 ^ 63 байта.
Следовательно, существует по крайней мере одна физическая величина, которая намного больше 64-разрядного целого числа со знаком (или без знака). Предполагая, что ваши единицы являются байтами . Если бы ваши единицы измерения были намного больше, например, GigaBytes, то все было бы в порядке, но ваша точность измерения была бы низкой.
Для другого примера рассмотрим далекие галактики. Галактика Андромеды на самом деле одна из ближайших, и она находится на расстоянии 2,5 * 10 ^ 6 световых лет. Если ваши единицы были милями , это было бы 14,5 * 10 ^ 18, больше, чем 64-разрядное целое число со знаком. Теперь, очевидно, это зависит от единиц измерения, которые вы используете для своих измерений, но некоторые галактики намного дальше, чем Андромеда. ( Самый дальний из известных - 13 * 10 ^ 9 LY ). В зависимости от точности, которую вы хотите для своего измерения, он может переполнить 64-битное целое число.
( Добавлено ) Да, мили - это паршивая единица астрономического расстояния. Более нормальной единицей может быть астрономическая единица , примерно 93 миллиона миль. Используя эту единицу измерения, самая дальняя известная галактика составляет примерно 10 ^ 15 а.е. (если моя математика верна), что соответствует 64-битному целому. Однако, если вы хотите измерить расстояние до Луны, до ближайших орбитальных спутников, эта единица слишком велика.
Еще один пример из электроники: Фарад (F), единица измерения емкости . Большие конденсаторы до 5 кФ. И это число, вероятно, со временем будет увеличиваться по мере улучшения гибридных автомобилей, «умных сетей» и т. Д. Однажды можно измерить емкость всего 10 ^ -18 F. Таким образом, общий диапазон "реальной" емкости, который мы можем измерить сегодня, составляет 5 * 10 ^ 21, больше, чем 64-битное целое число.
источник
Вам даже не нужно быть космическим, когда комбинаторика задействована. Есть 2 95 возможных сделок в игре в бридж, и это небольшая сложность.
источник
Самая важная физическая величина для вашего вопроса - это оперативная память компьютера .
Windows Server 2012 поддерживает до 4 ТБ физической памяти. Это 2 42 байта. Если объем оперативной памяти будет удваиваться примерно каждый год, то всего через 17 лет Windows Server 2032 будет поддерживать 2 62 байта физической памяти, и в это время вы
low + high
достигнете 2 63 - 2 и поцелуете максимальное 64-разрядное целое число со знаком.Я надеюсь, что ни одна критическая по безопасности система не выйдет из строя, так как предположим, что 64-битных всегда будет достаточно.
Для более общего использования наиболее важной физической величиной является адресное пространство памяти . (Полезно иметь гораздо большее адресное пространство, чем физическая память, например, чтобы поместить много стеков в память, все с возможностью расширения.) Современные реализации x86-64 поддерживают 48-битные виртуальные адреса, поэтому у нас есть только 14 лет, чтобы эти процессоры достигли 2 62 байта ограничения адресного пространства.
И еще есть распределенная разделяемая память «где (физически разделенные) памяти могут быть адресованы как одно (логически разделяемое) адресное пространство».
источник
0xFFFFFFFFxxxxxxxx
(т. Е. Более высокая половина ), например, операционная система или драйверы устройств.Не совсем. Есть много чисел, которые как больше, так и меньше, поэтому у нас есть числа с плавающей запятой. Числа с плавающей точкой компенсируют меньшую точность для лучшего диапазона.
В приведенном вами конкретном примере крайне маловероятно, что вам когда-нибудь понадобится число, которое больше этого. 64 бита соответствуют примерно 18 квинтиллионным элементам. Но никогда не говори никогда.
источник
Ваше предположение не будет обрабатывать физические величины, которые могут быть представлены только числами с плавающей запятой. И даже если вы решили масштабировать все числа, скажем, умножив все числа на 10000 (таким образом, значения все еще являются целыми числами, но могут быть представлены в десятитысячных долях), эта схема все еще не работает для чисел, очень близких к нулю, например, массы электрона (9,1094 * 10⎻⎻¹ кг).
Это очень реальная (и чрезвычайно малая) физическая величина , вот еще некоторые, с которыми у вас будут проблемы. И если вы утверждаете, что это не реальная физическая величина (даже если она в килограммах), подумайте:
Итак, вы видите, куда я иду с этим. Последний, с которым ты не справишься.
Конечно, у вас может быть специальное поле в числе, чтобы масштабировать целую часть вверх или вниз с помощью переменного множителя; ну и дела, вы только что изобрели с плавающей точкой.
источник
Сначала я бы ответил на вопрос, какие физические значения могут / должны быть представлены целым числом?
Целое число представляет собой представление натурального числа (и различий между ними) в компьютерной системе, поэтому применять его к чему-либо другому неправильно. Таким образом, использование расстояний или других величин, принадлежащих непрерывной области, не является аргументом. Для таких величин существуют действительные числовые представления. И вы всегда можете выбрать произвольно большой блок и подобрать любое значение с заданной точностью.
Итак, каковы физические значения, которые являются натуральными числами и могут ли они переполнять 64-битное целое число?
Я могу думать о двух. Количество физических объектов (таких как атомы) и энергетические уровни, на которых может находиться квантовая система. Это две вещи, которые являются строго целочисленными. Теперь я знаю, что вы можете разделить атом, но он все равно дает целое число, и вы не можете разделить его бесконечно. Оба из них могут легко превзойти 64-битный диапазон целого числа без знака . Количество атомов больше, и один атом может находиться в более чем одном энергетическом состоянии.
Если информация является физической или нет, очень спорно. Я бы сказал, что это не так. Поэтому я бы не сказал, что количество информации - это физическая вещь. Так что не объем оперативной памяти или что-то в этом роде. Если вы позволите это, то число атомов легко превосходит это число, потому что вам нужно более одного атома для хранения одного бита с помощью современной технологии.
источник
В дополнение к ответу Jerry101 я хотел бы предложить этот очень простой и практичный тест на правильность:
Предположим, вы распределяете некоторую память через
malloc
64-битную ОС. Давайте предположим, что распределитель памяти решает вернуть вам действительный блок памяти того размера, который вы запрашивали, но в котором установлен 63-й бит.Другими словами, давайте предположим, что существуют некоторые программные среды, в которых
0xFFFFFFFFxxxxxxxx
допустимые диапазоны памяти могут быть возвращены из вызоваmalloc
.Вопрос в том, будет ли ваш код работать так, как задумано?
Когда аналогичная ситуация возникает с 32-разрядными операционными системами, некоторые программы работают неправильно, если им присваиваются адреса памяти «в верхней половине». Первоначально считалось, что такие адреса памяти доступны только для привилегированного кода (операционные системы, драйверы устройств и периферийное оборудование), но из-за проблем с 32-разрядным адресным пространством поставщики ОС решили сделать часть этого зарезервированного пространства доступной для приложения, которые просят об этом.
К счастью, такая ситуация вряд ли случится с 64-битными программами какое-то время, по крайней мере, через десять лет.
Когда такая ситуация, наконец, происходит, это означает, что к тому времени 128-разрядные адресуемые процессоры и операционные системы стали бы мейнстримом и что они могли бы обеспечить «среду 64-разрядной эмуляции», позволяющую этим «устаревшим приложениям» работать. по предположениям, аналогичным современным 64-разрядным операционным системам.
Наконец, обратите внимание, что это обсуждение сосредоточено только на адресах памяти. Аналогичную проблему с метками времени следует принимать с большей осторожностью, поскольку определенные форматы меток времени выделяют много битов точности микросекундам и поэтому оставляют меньше битов, доступных для представления времени в будущем. Эти проблемы обобщены в статье Википедии о проблеме 2038 года .
источник
Это вопрос, который вы должны задать в каждом конкретном случае. Вы не должны использовать общее предположение о том, что 64-битной арифметике не будет переполнение, потому что даже тогда , когда правильные величины будут в гораздо меньшем диапазоне, злонамеренный источник данных может в конечном итоге дать вам необоснованные количества , которые могли бы переполнение, и это лучше , чтобы быть готов к этой ситуации, чем быть пораженным ею неожиданно.
В некоторых случаях имеет смысл написать код, который зависит от не переполнения 64-битных чисел. Основной класс примера, который я знаю, это счетчики, где счетчик увеличивается каждый раз, когда его используют. Даже со скоростью одного приращения в наносекунду (не практично) переполнение заняло бы больше столетия.
Обратите внимание, что хотя на первый взгляд может показаться, что «всегда неправильно» полагаться на «время до отказа» для правильности системы, мы делаем это все время с аутентификацией / входом в систему. При наличии достаточного количества времени (для перебора) любая такая система (основанная на паролях, закрытых ключах, токенах сеансов и т. Д.) Не работает.
источник
МОЖНО ли физическое количество не вписаться в 64 бита? Конечно. Другие указали подсчет количества атомов на Солнце или миллиметров до следующей галактики. Относятся ли такие случаи к вашей заявке, зависит от того, какая ваша заявка. Если вы подсчитываете количество предметов в любой данной корзине на вашем складе, 16 бит, скорее всего, будет достаточно. Если вы собираете статистику о количестве людей в мире, удовлетворяющих различным условиям, вам необходимо иметь возможность записывать миллиарды, поэтому вам потребуется более 32 бит, и в этот момент вы, вероятно, перейдете на 64 (так мало компьютеров). иметь встроенную поддержку 37-битных чисел и т. д.). Если это приложение для химии, которое рассчитывает количество атомов в молях, 64 битов будет недостаточно.
Технически, просто потому, что ни один компьютер сегодня не имеет 2 ^ 64 байта памяти, не обязательно означает, что индекс массива никогда не может быть больше чем 2 ^ 64. Существует концепция, называемая «разреженный массив», в которой многие элементы массива физически нигде не хранятся, и предполагается, что такие не сохраненные значения имеют некоторое значение по умолчанию, например, ноль или ноль. Но я предполагаю, что если вы пишете функцию для поиска в массиве или списке какого-либо вида, а размер поля, которое вы используете для хранения индекса в массиве, более чем вдвое превышает максимально возможный адрес, тогда выполняется проверка на переполнение, когда добавление двух индексов не будет строго необходимым.
источник
Неразумно предполагать, что 64-разрядное целое число может содержать все числа. Несколько причин:
Максимальное и минимальное 64-битное целое число являются конечными числами. Для каждого конечного числа существует большее и меньшее конечное число.
Расчеты с 128-битными и 256-битными числами в настоящее время используются в разных местах. Многие процессоры имеют специальные инструкции, которые работают с 128-битными целыми числами.
20 лет назад диск объемом 1 ГБ считался «большим». Сегодня диск объемом 1 ТБ считается маленьким. 20 лет назад средние рабочие столы имели около 16 МБ ОЗУ. Мой текущий рабочий стол имеет более 16 ГБ ОЗУ. В прошлом пространство на жестком диске и объем оперативной памяти росли в геометрической прогрессии, а в будущем прогнозируется их экспоненциальный рост. Если кто-то не может придумать очень вескую причину, почему он должен прекратить расти, не имеет смысла предполагать, что это прекратится.
источник