2014-01-07 20:18:51 +0000 2014-01-07 20:18:51 +0000
369
369

Если 32-битные машины могут обрабатывать только числа до 2^32, то почему я могу написать 10000000000 (триллионов) без сбоя моей машины?

32-битные компьютеры могут хранить только подписанные целые числа до 231 - 1. Поэтому у нас закончились IPv4-адреса и мы вступили в 64-битную эру.

Однако, число 231 - 1 (2,147,483,647) не так велико, как число 1 триллион (1,000,000,000), которое я, кажется, могу нормально отобразить без сбоя моей машины.

Кто-нибудь может объяснить, почему это так?

Ответы (18)

784
784
784
2014-01-07 20:31:38 +0000

Я отвечаю на ваш вопрос, задавая вам другой вопрос:

Как вы считаете на пальцах до 6?

Скорее всего, вы считаете до максимально возможного числа одной рукой, а затем переходите на вторую руку, когда у вас кончаются пальцы. Компьютеры делают то же самое, если они должны представлять значение больше, чем один регистр может держать они будут использовать несколько 32-битных блоков для работы с данными.

395
395
395
2014-01-07 20:36:34 +0000

Вы правы, что 32-битное целое число не может содержать значения больше 2^32-1. Однако, значение этого 32-битного целого и то, как оно отображается на экране, - это две совершенно разные вещи. Выведенная строка “1000000000000” не представлена 32-битным целым числом в памяти.

Для буквального отображения числа “1000000000000” требуется 13 байт памяти. Каждый отдельный байт может содержать значение до 255. Ни один из них не может содержать полного, численного значения, но интерпретируется индивидуально как ASCII символы (например, символ ‘0’ представлен десятичным значением 48, двоичным значением 00110000), они могут быть сведены вместе в формат, который имеет смысл для вас, человека.

  • *

Сопутствующее понятие в программировании typecasting, то есть, как компьютер будет интерпретировать определенный поток 0s и 1s. Как и в вышеприведенном примере, оно может быть интерпретировано как числовое значение, символ или даже что-то совершенно другое. В то время как 32-битное целое число может не иметь значения 1000000000000, 32-битное число с плавающей запятой сможет, используя совершенно другую интерпретацию.

Что касается того, как компьютеры могут работать с большими числами и обрабатывать их внутри себя, то существуют 64-битные целые числа (которые могут вместить значения до 16 миллиардов), значения с плавающей запятой, а также специализированные библиотеки, которые могут работать с произвольно большими числами.

190
190
190
2014-01-07 21:37:16 +0000

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

Во-вторых, 1 триллион и 10000000000 - это две разные вещи.

  • 1 триллион - это абстрактное понятие числа
  • 1000000000000 - это текст

Нажимая 1 раз, а затем 0 12 раз, вы набираете текст. 1 вход 1, 0 вход 0. Видите? Вы печатаете символы. Символы не являются цифрами. Печатные машинки вообще не имели ни процессора, ни памяти, и они довольно хорошо обрабатывали такие “числа”, потому что это просто текст.

Доказательство того, что 100000000 не число, но text: это может означать 1 триллион (в десятичной системе), 4096 (в двоичной системе) или 281474976710656 (в шестнадцатеричной системе). В разных системах он имеет еще больше значений. Значение 1000000000000 - число, а хранение - это другая история (вернемся к ней через мгновение).

Для хранения текста (в программировании это называется string) 10000000000 нужно 14 байт (по одному для каждого символа плюс завершающий NULL-байт, что по сути означает “строка заканчивается здесь”). Это 4 машинных слова. 3-х с половиной было бы достаточно, но, как я уже говорил, операции с машинными словами выполняются быстрее всего. Предположим, что для хранения текста используется ASCII , поэтому в памяти это будет выглядеть следующим образом: (преобразование ASCII кодов, соответствующих 0 и 1, в двоичный, каждое слово в отдельной строке)

00110001 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00000000 00000000 00000000

Четыре символа помещаются в одно слово, остальное перемещается в следующее. Остальное перемещается к следующему слову до тех пор, пока все (включая первый NULL байт) не подойдет.

Теперь вернемся к хранению чисел. Это работает так же, как и с переполненным текстом, но они подгоняются справа налево. Это может показаться сложным, так что вот пример. Для простоты предположим, что:

  • наш воображаемый компьютер использует десятичное число вместо двоичного
  • один байт может хранить числа 0..9
  • одно слово состоит из двух байтов

  • здесь пустая память на 2 слова:

0 0
0 0

Сохраним число 4:

0 4
0 0

Теперь добавим 9:

1 3
0 0

Заметьте, что оба операнда поместятся в один байт, но не в результат. Но у нас есть еще один готовый к использованию. Теперь сохраним 99:

9 9
0 0

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

0 0
0 0

Упс… Это называется integer overflow и является причиной многих серьезных проблем, иногда очень дорогих .

Но если мы ожидаем, что переполнение произойдет, мы можем сделать так:

0 0
9 9

А теперь добавьте 1:

0 1
0 0

Становится понятно, если удалить разделение байтов и newline:

0099 | +1
0100

Мы предсказали, что переполнение может произойти, и нам может понадобиться дополнительная память. Работа с числами таким образом не так быстра, как с числами, которые помещаются в отдельные слова, и это должно быть реализовано в программном обеспечении. Добавление поддержки двух-32-битных номеров в 32-битный процессор фактически делает его 64-битным процессором (теперь он может работать с 64-битными числами нативно, не так ли?).

Все, что я описал выше, относится к бинарной памяти с 8-битными байтами и 4-байтными словами, работает практически так же:

00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111 | +1
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000

Преобразование таких чисел в десятичную систему - сложная задача, однако. (но это довольно хорошо работает с шестнадцатеричной ]

40
40
40
2014-01-07 23:06:37 +0000

Вы также можете написать “НАСТОЯЩЕЕ ГОСУДАРСТВО - ДЕЙСТВИЕ” без сбоев компьютера :) @ Ответ Скотта является локальным для некоторых фреймворков вычислений, но ваш вопрос о “написании” большого числа подразумевает, что это просто текст, по крайней мере, до тех пор, пока он не будет интерпретирован.

Edit: теперь с ~~~ без сарказма~~~ более полезная информация о различных способах хранения номер в памяти. Я буду описывать их с помощью higher abstract, т.е. в терминах, в которых современный программист может писать код до его трансляции в машинный код для выполнения.

Данные на компьютере должны быть ограничены определенным типом, а машинное определение такого типа описывает, какие операции можно выполнять с этими данными и как (т.е. сравнивать числа, конкатенировать текст или XOR булевой). Нельзя просто добавить текст к числу, так же как нельзя умножить число на текст, чтобы некоторые из этих значений можно было преобразовывать между типами.

Начнем с unsigned integers. В этих типах значений для хранения информации о цифрах используются все биты; ваш пример 32-битного беззнакового целого, где может храниться любое значение от 0 до 2^32-1. И да, в зависимости от языка или архитектуры используемой платформы, Вы можете иметь 16-битные целые числа или 256-битные целые числа.

Что, если Вы хотите получить отрицательное значение? Интуитивно signed integers - это название игры. Конвенция заключается в том, чтобы распределить все значения от -2^(n-1) до 2^(n-1)-1 - таким образом мы избежим путаницы, связанной с двумя способами записи +0 и -0. Таким образом, 32-битное подписанное целое число будет содержать значение от -2147483648 до 2147483647. Хорошо, правда?

Хорошо, мы рассмотрели целые числа, которые являются числами без десятичной составляющей. Выражение этих чисел более хитрое: нецифровая часть может разумно находиться только где-то между 0 и 1, поэтому каждый дополнительный бит, используемый для описания, увеличит его точность: ½, ¼, 1/8…. Проблема в том, что вы не можете точно выразить простую десятичную 0.1 как сумму дроби, которая может иметь только две силы в их знаменателе! Не будет ли гораздо проще сохранить число как целое число, но согласиться поставить вместо него точку с радиусом (десятичную)? Это называется fixed point numbers, где мы храним 1234100, но соглашаемся на соглашение, чтобы читать его как 1234.100.

Относительно более распространенным типом, используемым для вычислений, является floating point. Принцип его работы очень аккуратный, он использует один бит для хранения знакового значения, затем некоторые - для хранения экспоненты и знакового значения. Существуют стандарты, определяющие такие распределения, но для 32-битного float максимальное число, которое можно было бы сохранить - это подавляющее

(2 - 2^-23) * 2^(2^7 - 1) ≈ 3.4 * 10^38

Это, однако, достигается за счет точности. JavaScript, доступный в браузерах, использует 64-битные float, и все равно не может все исправить. Просто скопируйте это в адресную строку и нажмите enter. Предупреждение спойлера: результат not будет 0.3.

javascript:alert(0.1+0.2);

Есть больше альтернативных типов, таких как Microsoft .NET 4.5’s BigInteger , который теоретически не имеет верхней или нижней границы и должен быть вычислен “партиями”; но, возможно, более увлекательными технологиями являются те, которые understand math, как движок системы Wolfram Mathematica, который может точно работать с абстрактными значениями, такими как бесконечность .

31
31
31
2014-01-07 21:58:50 +0000

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

Правда, если компьютер настаивает на хранении чисел с помощью простого двоичного представления числа с использованием одного слова (4 байта на 32-битной системе), то 32-битный компьютер может хранить числа только до 2^32. Но есть и множество других способов кодирования чисел в зависимости от того, чего вы хотите с ними добиться.

Одним из примеров является то, как компьютеры хранят числа с плавающей точкой. Компьютеры могут использовать целую кучу различных способов их кодирования. Стандарт IEEE 754 определяет правила для кодирования чисел больше 2^32. Грубо говоря, компьютеры могут реализовать это, разделив 32 бита на разные части, представляющие некоторые цифры числа, и другие биты, представляющие size числа (т.е. экспоненту, 10^x). Это позволяет получить гораздо больший диапазон чисел в терминах размера, но компрометирует точность (что нормально для многих целей). Конечно, компьютер также может использовать для этой кодировки более одного слова, увеличивая точность величины доступных кодированных чисел. Простая 32 десятичная версия стандарта IEEE позволяет использовать числа с точностью до 7 десятичных цифр и числа с амплитудой до 10^96.

Но есть много других вариантов, если вам нужна дополнительная точность. Очевидно, что вы можете использовать больше слов в кодировке без ограничений (хотя и с неустойкой производительностью для преобразования в кодированный формат и из него). Если вы хотите исследовать один из способов, как это сделать, есть отличный open-source надстройка для Excel, которая использует схему кодирования, позволяющую вычислять сотни цифр точности. Надстройка называется Xnumbers и доступна здесь . Код находится в Visual Basic, который не является самым быстрым, но имеет то преимущество, что его легко понять и модифицировать. Это отличный способ узнать, как компьютеры достигают кодирования более длинных чисел. И вы можете поиграть с результатами в Excel без необходимости установки каких-либо инструментов программирования.

24
24
24
2014-01-07 23:47:36 +0000

Это все в твоем вопросе.

Ты можешь писать любой номер, который тебе нравится на бумаге. Попробуйте написать триллион точек на белом листе бумаги. Это медленно и неэффективно. Вот почему у нас есть 10-значная система для представления этих больших чисел. У нас даже есть имена для больших чисел, такие как “миллион”, “триллион” и другие, так что не говорите one one one one one one one one one one one... вслух. 32-битные процессоры

разработаны для наиболее быстрой и эффективной работы с блоками памяти, которые имеют ровно 32 двоичных разряда в длину. Но мы, люди, обычно используем 10-значную числовую систему, а компьютеры, будучи электронными, используют 2-значную систему двоичную ). Цифры 32 и 64 - это просто 2. Как и миллион и триллион - это 10. Нам легче работать с этими числами, чем, например, с множествами 65536.

Мы разбиваем большие числа на цифры, когда пишем их на бумаге. Компьютеры разбивают числа на большее количество цифр. Мы можем записывать любые числа, которые нам нравятся, и компьютеры тоже могут, если мы их проектируем.

15
15
15
2014-01-08 00:42:45 +0000

32-битные и 64-битные относятся к адресам памяти. Память вашего компьютера похожа на почтовые ящики, каждый из которых имеет свой адрес. ЦПУ (центральный процессор) использует эти адреса для адресации ячеек памяти в оперативной памяти (Random Access Memory). Когда центральный процессор мог обрабатывать только 16-битные адреса, вы могли использовать только 32 Мб оперативной памяти (которая в то время казалась огромной). С 32 бит он перешел на 4+gb (что в то время казалось огромным). Теперь, когда у нас есть 64-битные адреса, оперативная память уходит в терабайты (что казалось огромным). Однако программа способна выделять несколько блоков памяти для таких вещей, как хранение чисел и текста, что зависит от программы и не связано с размером каждого адреса. Так что программа может сказать процессору, что я собираюсь использовать 10 адресных блоков памяти, а затем хранить очень большое число, или строку из 10 букв, или что-то в этом роде. Боковая заметка: на адреса памяти указывают “указатели”, поэтому 32- и 64-битное значение означает размер указателя, используемого для доступа к памяти.

13
13
13
2014-01-08 06:44:38 +0000

Потому что отображение числа производится с использованием отдельных символов, а не целых чисел. Каждая цифра в числе представлена отдельным символьным литералом, целое значение которого определяется используемой кодировкой, например, 'a' представлена со значением ascii 97, а '1' представлена со значением 49. Проверьте таблицу ascii table здесь . Для отображения и ‘a’, и ‘1’ одинаковы. Это символьные литералы, а не целые числа. Каждый символьный литерал должен иметь максимальное значение 255 в 32-битной платформе, сохраняя значение в 8 бит или 1 байт (Это зависит от платформы, однако 8 бит - это наиболее распространенный размер символа), таким образом, они могут быть сгруппированы и отображены. Сколько отдельных символов они могут отображаться, зависит от имеющейся оперативной памяти. Если у вас всего 1 байт оперативной памяти, то вы можете отобразить только один символ, если у вас 1 Гб оперативной памяти, то вы можете хорошо отобразить 1024*1024*1024 символы(Слишком лениво подсчитывать).

Это ограничение, однако, относится и к вычислениям, однако, я полагаю, что вас интересует стандарт IPV4. Хотя он не полностью связан с bit-size компьютеров, он каким-то образом повлиял на стандарты. При создании стандарта IPV4 значения ip хранились в 32-битных целых числах. Теперь, как только вы задали размер, он стал стандартом. Всё, что мы знаем об Интернете, зависело от этого, а потом у нас закончились IP-адреса для присвоения. Так что если IP-стандарт был переработан на 64 бита, то все просто перестанет работать, включая ваш маршрутизатор (я полагаю, что это правильно) и другие сетевые устройства. Так что нужно создать новый стандарт, который просто поменял 32-битное целое на 128-битное. И скорректировал остальную часть стандарта. Производителю оборудования просто нужно заявить, что он поддерживает этот новый стандарт, и он станет вирусным. Хотя все не так просто, но, думаю, вы поняли суть.

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

13
13
13
2014-01-08 11:27:08 +0000

В процессорах есть “слова”. Есть разные слова. Когда говорят “32-битный процессор”, то в основном подразумевают “ширину шины памяти”. Это слово состоит из различных “полей”, которые относятся к подсистемам ЭВМ, соответствующим передаче (24 бита) и управлению (другие биты). Я могу ошибаться насчет точных чисел, убедитесь в этом через мануалы.

Совершенно другой аспект - это вычисления. В SSE и MMX наборах инструкций могут храниться длинные целые числа. Максимальная длина без потери производительности зависит от текущей версии SSE, но она всегда кратна 64 битам.

Текущие процессоры Opteron могут обрабатывать 256-битные числа (я не уверен насчет целого числа, но float это точно).

Сводная информация : (1) ширина шины напрямую не связана с шириной вычисления, (2) даже разные слова (слово памяти, регистровое слово, слово шины и т.д.) не связаны друг с другом, в противном случае у них общий дивизор около 8 или 16 или 24. Многие процессоры даже использовали 6-битное слово (но его история).

10
10
10
2014-01-08 20:39:13 +0000

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

Программное обеспечение - это код, который говорит машине, как принимать данные, как их обрабатывать, как их хранить и как предоставлять их другим.

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

Программное обеспечение подсказывает машине, как обрабатывать числа. Если программа предназначена для работы с большими числами, она посылает в ЦПУ серию инструкций, которые говорят ей, как работать с большими числами. Например, ваш номер может быть представлен двумя 32-битными регистрами. Если вы хотите добавить 1234 к вашему числу, программа скажет процессору сначала добавить 1234 к нижнему регистру, а затем проверить бит переполнения, чтобы посмотреть, не привело ли это сложение к числу слишком большому для нижнего регистра. Если да, то он добавляет 1 к верхнему регистру.

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

8
8
8
2014-01-09 15:18:54 +0000

32-битные компьютеры могут хранить числа до 2^32 в одном машинном слове, но это не значит, что они не могут обрабатывать большие сущности данных.

Смысл 32-битного компьютера обычно заключается в том, что шина данных и адресная шина имеют ширину 32 бита, что означает, что компьютер может обрабатывать одновременно 4 ГБ адресного пространства памяти и посылать по шине данных четыре байта данных за один раз.

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

Обычный 32-битный процессор Intel может обрабатывать 128-битные числа внутри, что позволяет без проблем обрабатывать такие числа, как 100000000000000000000000000000000000000.

Вы можете обрабатывать гораздо большие числа, чем в компьютере, но тогда вычисления должны выполняться программным обеспечением, процессор не имеет инструкций по работе с числами больше 128 бит. (Он может обрабатывать гораздо большие числа в виде чисел с плавающей точкой, но тогда у вас будет только 15 цифр точности).

6
6
6
2014-01-10 19:11:43 +0000

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

“32 bit” относится к ширине адреса памяти. Это не имеет никакого отношения к размеру регистра. Многие 32-битные процессоры, скорее всего, имеют 64 или даже 128-битные регистры. В частности, говоря о линейке x86, последние потребительские процессоры, все 64-битные, имеют до 256 битных регистров для специальных целей.

Эта разница между шириной регистра и шириной адреса существует с древних времен, когда у нас было 4 битных регистра и 8 битных адресов, или наоборот.

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

Причина, по которой регистры, какого бы размера они ни были, могут дополнительно calculate с большими числами, заключается в том, что слишком большие вычисления могут быть разбиты на несколько более мелких, которые действительно помещаются в регистры (это просто крошечный бит, который на самом деле сложнее).

6
6
6
2014-01-10 21:36:01 +0000

Ответы, которые уже были даны, на самом деле довольно хороши, но они, как правило, касаются вопроса с разных сторон и, таким образом, представляют неполную картину. Они также, на мой взгляд, слишком техничны.

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

Вы смешиваете несколько концепций в вашем вопросе, и одна из них (“32 бита”) на самом деле может относиться к целому ряду различных вещей (и различные ответы предполагают различные интерпретации). Все эти понятия как-то связаны с количеством битов (1 и 0), используемых (или доступных) в различных вычислительных контекстах (что я имею в виду, надеюсь, будет разъяснено примерами ниже), но эти понятия в противном случае не связаны.

Прямо:

  • “IPv4/6” относится к интернет-протоколу , набору правил, определяющих, как информация должна быть упакована и интерпретирована в интернете. Основное (или, по крайней мере, наиболее известное) различие между IPv4 и IPv6 заключается в том, что адресное пространство (т.е. набор адресов, который может быть использован для различения различных местоположений в сети) больше в IPv6. Это связано с тем, сколько бит в каждом пакете данных, отправленном по сети, выделяется для (т.е. выделяется для целей) идентификации отправителя и предполагаемого получателя пакета.
  • Невычислительная аналогия: Каждый пакет похож на письмо, отправленное по улитке, а адресное пространство похоже на количество символов, которые “разрешено” использовать при написании адреса и обратного адреса на конверте.
  • Я не вижу этого упоминания ни в одном из других ответов до сих пор.
  • Компьютерно-памятные “слова” (32-битные и 64-битные) в общем случае можно считать наименьшим количеством данных, которые компьютер использует, или “думает”. Эти биты данных собираются вместе, чтобы составить другие биты данных, такие как куски текста или более крупные целые числа.
  • Невычислительная аналогия: слова могут восприниматься как немного похожие на буквы, составляющие слова на бумаге, или даже как отдельные слова в цепочке мыслей.
  • См. ответ Гуффы ](https://superuser.com/a/699275/199803), ответ Санариса ](https://superuser.com/a/698615/199803), и первый абзац gronostaj’s answer .
  • 32-битные указатели могут быть или не быть словами, но, тем не менее, они рассматриваются атоматически (т.е. как отдельные единицы, которые не могут быть разбиты на более мелкие составляющие). Указатели - это самый низкоуровневый способ, с помощью которого компьютер может записать в память некоторый произвольный объем данных. Обратите внимание, что размер указателя, используемый компьютером (или, по сути, операционной системой), ограничивает диапазон памяти, к которой может обращаться один указатель, так как существует только максимально возможное количество ячеек памяти, на которые указатель может “указывать”, так как есть возможные значения для самого указателя. Это аналогично тому, как IPv4 ограничивает диапазон возможных адресов в Интернете, но при этом not ограничивает объем данных, которые могут присутствовать, например, на конкретной веб-странице. Однако, размер указателя not ограничивает размер самих данных, на которые может указывать указатель. (Пример схемы, позволяющей размер данных превышать диапазон указателей, можно посмотреть в Linux’s inode pointer structure . Обратите внимание, что использование слова “указатель” несколько отличается от типичного, так как указатель обычно ссылается на указатель в оперативной памяти, а не на место на жестком диске)
  • Невычислительная аналогия: хммм…. эта немного хитрая штука. Возможно, десятичная система индексации библиотечных материалов Дьюи немного похожа? Или любая другая система индексации.
  • См. ответ SiteNook .
  • Пожалуйста, обратите внимание, что мое объяснение указателей выше элиминирует некоторые тонкие детали и, возможно, не совсем корректно. Однако, в языках программирования, где программисты работают непосредственно с указателями, ментального режима, который я нарисовал, обычно достаточно для практических целей.
  • номера, которые компьютер “способен отобразить ” не ограничены (для практических целей) аппаратным обеспечением или операционной системой компьютера; к ним относятся, как к любому другому тексту.
  • Невычислительная аналогия: написание на листе бумаги
  • Смотрите user1306322’s answer и Bigbio2002’s answer

Заметьте, что это не претендует на исчерпывающий список интерпретаций фразы “32 бита”

Дополнительная благодарность: чтобы действительно увидеть философское различие между пустыми костями чисел и примитивными кусками компьютерной памяти, прочитайте немного о Turing machines .

5
5
5
2014-01-11 23:24:10 +0000

В твоем сознании ты знаешь только 10 разных цифр. от 0 до 9. Внутри вашего мозга это, конечно, кодируется иначе, чем в компьютере.

Компьютер использует биты для кодирования чисел, но это не важно. Просто инженеры так решили кодировать вещи, но вы должны это игнорировать. Можно считать, что 32-битный компьютер имеет уникальное представление более 4 миллиардов различных значений, в то время как у нас, людей, уникальное представление для 10 различных значений.

Всякий раз, когда мы должны понять большее число, мы используем систему. Самое левое число является самым важным. Оно в 10 раз важнее следующего.

Компьютер, способный различать четыре миллиарда различных значений, аналогичным образом должен сделать самое левое значение, в наборе значений, в четыре миллиарда раз более важным, чем следующее значение в этом наборе. На самом деле компьютеру все равно. Он не присваивает “значение” числам. Программисты должны сделать специальный код, чтобы позаботиться об этом.

Всякий раз, когда значение становится больше, чем количество уникальных символов, 9 в человеческом сознании, вы добавляете одно к числу слева.

3+3=6

В этом случае, число все еще помещается в один “слот”

5+5=10. This situation is called an overflow.

Таким образом, люди всегда сталкиваются с проблемой недостаточного количества уникальных символов. Если только компьютер не имеет системы, чтобы справиться с этим, он просто напишет 0, забыв, что есть лишнее число. К счастью, на компьютере есть “флаг переполнения”, который в этом случае поднимается.

987+321 is more difficult.

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

7+1=8, we now have ...8 as the result so far

Затем вы перемещаетесь в следующий слот и выполняете то же самое добавление.

8+2=10, the overflow flag is raised. We now have ...08, plus overflow.

Поскольку у нас было переполнение, это означает, что мы должны добавить 1 к следующему числу.

9+3=12, and then we add one due to overflow. ...308, and we had another overflow.

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

1308

Компьютер делает это точно так же, за исключением того, что у него 2^32 или даже лучше 2^64 различных символов, вместо 10, как у людей.

На аппаратном уровне, компьютер работает на одних битах, используя точно такой же метод. К счастью, для программистов это абстрагируется. Биты - это всего две цифры, потому что это легко представить в линии электропередач. Или свет горит, или выключен.

Наконец, компьютер может отображать любое число в виде простой последовательности символов. Вот в чем компьютер лучше всего разбирается. Алгоритм преобразования между последовательностью символов и внутренним представлением довольно сложен.

5
5
5
2014-01-11 17:59:58 +0000

В случае, если вам нужен практический пример того, сколько программ в типичной системе Linux обрабатывает и выводит большое количество:

libgmp - Библиотека GNU Multiple Precision Arithmetic Library является наиболее широко используемой библиотекой для этих целей в системах Linux. Простой пример умножения 2^80 на 1000:

#include <gmp.h>

// Each large integer uses the mpz_t type provided by libgmp
mpz_t a_large_number;
mpz_t base;
mpz_t result;

// Initalize each variable
mpz_init(a_large_number);
mpz_init(base);
mpz_init(result);

// Assign the number 2 to the variable |base|
mpz_set_ui(base, 2);

// Raise base^80 (2^80), store the result in |a_large_number|
mpz_pow_ui(a_large_number, base, 80);

// Multiply |a_large_number| by 1000, store the result in |result|
mpz_mul_ui(result, a_large_number, 1000);

// Finally, output the result in decimal and hex notation
gmp_printf("decimal: %Zd, hex: %ZX\n", result, result);

Так что в основном это то же самое, что использовать обычные операторы + - * /, просто с библиотекой для разбиения чисел и их внутреннего хранения в виде нескольких машинных слов размером (т.е. 32-битных) чисел. Есть также функции типа scanf() для обработки преобразования текста, вводимого в целочисленные типы.

Структура mpz_t точно такая же, как в примере Скотта Чемберлена (Scott Chamberlain), который считал до 6 с помощью двух рук. В основном это массив типов mp_limb_t машинного слова, и когда число слишком велико, чтобы поместиться в машинное слово, GMP использует несколько mp_limb_t для хранения высоких/нижних частей числа.

5
5
5
2014-01-09 16:36:20 +0000

Если вы запишете 1000000000000, например, в калькулятор, то компьютер вычислит его как тип реальности число с десятичной точкой. Ограничение на 32 бита, о котором вы говорили, больше касается всех Типа integer чисел без десятичной запятой. Разные типы данных используют разные методы попадания в битах/байтах.

Номер типа ввода : Эта таблица поможет вам уловить точку http://msdn.microsoft.com/en-us/library/296az74e.aspx ). Это касается ограничений для C++. Например, номер типаInt64 имеет ограничения от -9223372036854775808 до 9223372036854775807.

Номер типа Reeal : Реальные номера типа содержат значение с плавающей точкой и экспонентом, и вы можете ввести гораздо большие числа, но с ограниченной точностью/точностью. http://msdn.microsoft.com/en-us/library/6bs3y5ya.aspx ) Например, LDBL (большой дубль) в C++ имеет максимальный экспонент 308, так что, возможно, вы можете ввести или иметь в результате число 9.999 x 10^308, это означает, что теоретически вы будете иметь 308(+1) цифр 9, но только 15 самых важных цифр будут использованы для его представления, остальное будет потеряно, из-за ограниченной точности.

Дополнительно, существуют различные языки программирования, и они могут иметь различные реализации ограничений на количество. Поэтому можно представить, что специализированные приложения могут обрабатывать гораздо большие (и/или более точные/точную) цифры, чем C++.

3
3
3
2014-01-12 00:41:20 +0000

Потому что вы отображаете не число (в том, что касается компьютера), а строка , или последовательность цифр. Конечно, некоторые приложения (например, калькулятор, я полагаю), которые работают с числами, могут обрабатывать такие числа, я полагаю. Я не знаю, какие трюки они используют… Я уверен, что некоторые другие, более сложные ответы покрывают это.

0
0
0
2016-12-30 11:54:31 +0000

Большая часть содержания этого ответа изначально пришла из этот ответ (написанный до этого другой вопрос был помечен как дубликат). Поэтому я обсуждаю использование 8-битных значений (хотя этот вопрос касался 32-битных значений), но это нормально, потому что 8-битные значения проще понять концептуально, и те же самые понятия применимы к большим значениям, например, 32-битной арифметике.

Когда вы добавляете два числа, которые являются 8-битными, наибольшее число, которое вы можете получить (0xFF + 0xFF = 1FE). На самом деле, если вы умножите два числа, которые являются 8-битными, наибольшее число, которое вы можете получить (0xFF * 0xFF = 0xFE01), все равно будет 16-битным, дважды 8-битным.

Теперь, вы можете предположить, что x-битный процессор может отслеживать только x-битные значения. (Например, 8-битный процессор может отслеживать только 8 бит.) Это неточно. 8-битный процессор получает данные в 8-битных кусочках (Эти “кусочки” обычно имеют формальный термин: “слово”. На 8-ми битном процессоре используются 8-битные слова. На 64-битном процессоре могут использоваться 64-битные слова.)

Таким образом, когда вы даете компьютеру 3 байта: Байт #1: Инструкция MUL Байт #2: байты старшего порядка (например, 0xA5) Байт #3: байты нижнего порядка (например, 0xCB) Компьютер может сгенерировать результат, превышающий 8 бит. ЦП может выдавать такие результаты: 0100 0000 0100 0010 xxxxx xxxx xxxx xxxx 1101 0111 a.k.a.: 0x4082xxxxD7 Теперь, позвольте мне интерпретировать это для вас: 0x просто означает, что следующие цифры являются шестнадцатеричными.
я рассмотрю “40” более подробно. 82 - это часть регистра “A”, который представляет собой серию из 8 бит. xx и xx - это часть двух других регистров, названных регистром “B” и регистром “C”. Причина, по которой я не заполнил эти биты нулями или единицами, заключается в том, что команда “ADD” (посылаемая в CPU) может привести к тому, что эти биты останутся неизменными командой (в то время как большинство других битов, которые я использую в этом примере, могут быть изменены, за исключением некоторых флаговых битов). D7 поместится в большее количество бит, называемых регистром “D”. Регистр “A” - это всего лишь часть памяти. Регистры встроены в процессоры, так что процессор может обращаться к регистрам без необходимости взаимодействия с памятью на карте памяти.

Так что математический результат 0xA5 умноженный на 0xCB равен 0x82D7.

Теперь, почему биты разделились на регистры A и D, а не на регистры A и B, или на регистры C и D? Ну, опять же, это пример сценария, который я использую, имея в виду довольно схожий по концепции с реальным языком ассемблера (Intel x86 16-битный, используемый в Intel 8080 и 8088 и многими более новыми процессорами). Могут быть некоторые общие правила, такие как регистр “C”, обычно используемый в качестве индекса для подсчета операций (типичный для циклов), и регистр “B”, используемый для отслеживания смещений, которые помогают указывать места в памяти. Таким образом, “A” и “D” могут быть более распространены для некоторых общих арифметических функций.

Каждая инструкция для CPU должна иметь некоторую документацию, используемую людьми, которые программируют на Ассемблере. Эта документация должна указывать, какие регистры используются каждой командой. (Так что выбор, какие регистры использовать, часто задается проектировщиками ЦП, а не программистами языка Ассемблера. Хотя, может быть некоторая гибкость.)

Сейчас, возвращаясь к “40” в приведённом выше примере: это серия бит, часто называемая “регистром флагов”. Каждый бит в регистре флагов имеет имя. Например, есть “переполнение” бита, которое может быть установлено процессором, если полученный результат больше пространства, которое может хранить один байт результата. (К биту “переполнения” часто можно отнести сокращенное имя “OF”. Это заглавное “о”, а не “ноль”). Программное обеспечение может проверить значение этого флага и заметить “проблему”. Работа с этим битом часто невидимо обрабатывается языками более высокого уровня, поэтому начинающие программисты часто не знают, как взаимодействовать с флагами процессора. Тем не менее, программисты, занимающиеся ассемблировкой, могут часто обращаться к некоторым из этих флагов так же, как и к другим переменным.

Например, у вас может быть несколько инструкций ADD. Одна команда ADD может хранить 16 бит результатов в регистре A и регистре D, в то время как другая команда может просто хранить 8 младших битов в регистре A, игнорировать регистр D и указывать бит переполнения. Затем, позже (после хранения результатов регистра A в оперативной памяти), вы можете использовать другую инструкцию ADD, которая хранит только 8 младших битов в регистре (возможно, в регистре A.) Необходимость использования флага переполнения может зависеть от того, какую инструкцию по умножению вы используете.

(Также часто встречается флаг “переполнения”, на случай, если вы вычитаете слишком много, чтобы вписаться в желаемый результат)

Просто чтобы показать вам, как все запуталось: Intel 4004 был 4-битным процессором Intel 8008 был 8-битным процессором. Он имел 8-битные регистры A, B, C и D. Intel 8086 был 16-битным процессором. Он имел 16-битные регистры с именами AX, BX, CX и DX. Intel 80386 представлял собой 32-битный процессор. Он имел 32-битные регистры EAX, EBX, ECX и EDX. Процессоры Intel x64 имеют 64-битные регистры RAX, RBX, RCX и RDX. Микросхемы x64 могут выполнять 16-битный код (в некоторых режимах работы), а также интерпретировать 16-битные инструкции. При этом биты, составляющие регистр AX, составляют половину битов, составляющих регистр EAX, а это половина битов, составляющих регистр RAX. Поэтому при изменении значения AX также меняются EAX и RAX, поскольку те биты, которые используются AX, являются частью битов, используемых RAX. (Если вы изменяете EAX на значение, кратное 65 536, то младшие 16 битов остаются неизменными, поэтому AX не изменяется. Если изменить EAX на значение, не кратное 65 536, то это повлияет и на AX.)

Есть больше флагов и регистров, чем только те, о которых я упоминал. Для простого концептуального примера я выбрал несколько общеупотребительных.

Теперь, если вы работаете на 8-битном процессоре, то при записи в память вы можете обнаружить некоторые ограничения на возможность обращения к 8-битному адресу, а не к 4-битному или 16-битному. Детали будут варьироваться в зависимости от процессора, но если у Вас есть такие ограничения, то процессор может иметь дело с 8-битными словами, поэтому процессор чаще всего называют “8-битным процессором”.