32-разрядные компьютеры могут хранить только целые числа со знаком до 2 31 - 1.
Именно поэтому у нас закончились адреса IPv4 и мы вступили в 64-разрядную эру.
Тем не менее, число 2 31 - 1 (2 147 483 647) не так велико, как число 1 триллион (1 000 000 000 000), которое, как мне кажется, я могу вывести на экран без поломки моей машины.
Может кто-нибудь объяснить, почему это так?
10^9
без сбоя моего ПК?» а скорее "Как я могу писать10^(18)
без разрушения моего мозга?"Ответы:
Я отвечаю на ваш вопрос, задавая вам другой:
Вы, вероятно, рассчитываете до максимально возможного числа одной рукой, а затем переходите к второй руке, когда у вас кончатся пальцы. Компьютеры делают то же самое, если им нужно представить значение больше, чем может вместить один регистр, они будут использовать несколько 32-битных блоков для работы с данными.
источник
Вы правы, что 32-разрядное целое число не может содержать значение больше 2 ^ 32-1. Однако значение этого 32-разрядного целого числа и то, как оно отображается на экране, - это две совершенно разные вещи. Напечатанная строка «1000000000000» не представлена 32-разрядным целым числом в памяти.
Для буквального отображения числа «1000000000000» требуется 13 байт памяти. Каждый отдельный байт может содержать значение до 255. Ни один из них не может содержать все числовое значение, но интерпретируется индивидуально как символы ASCII (например, символ '
0
' представлен десятичным значением 48, двоичное значение00110000
), они могут быть объединенным в формат, который имеет смысл для вас, человека.Связанное понятие в программировании - это приведение типов , то есть, как компьютер будет интерпретировать определенный поток
0
s и1
s. Как и в приведенном выше примере, его можно интерпретировать как числовое значение, символ или даже что-то еще целиком. Хотя 32-разрядное целое число может не содержать значение 1000000000000, 32-разрядное число с плавающей запятой сможет это сделать, используя совершенно другую интерпретацию.Что касается того, как компьютеры могут работать и обрабатывать большие числа внутри, существуют 64-разрядные целые числа (которые могут содержать значения до 16 миллиардов миллиардов), значения с плавающей запятой, а также специализированные библиотеки, которые могут работать с произвольно большими номера.
источник
1000000000000
точно. Сейчас 10 ^ 12 или 2 ^ 12 * 5 ^ 12; 5 ^ 12 требует 28 бит мантиссы.Прежде всего, 32-разрядные компьютеры могут хранить числа до 2³²-1 в одном машинном слове . Машинное слово - это объем данных, которые ЦП может обработать естественным образом (т. Е. Операции с данными такого размера выполняются аппаратно и обычно выполняются быстрее всего). 32-битные процессоры используют слова, состоящие из 32 бит, поэтому они могут хранить числа от 0 до 2³²-1 в одном слове .
Во-вторых, 1 триллион и 1000000000000 - это две разные вещи.
Нажав 1один раз, а затем 012 раз, вы печатаете текст. 1входы
1
, 0входы0
. Видеть? Вы печатаете символы. Символы не цифры. У пишущих машинок вообще не было процессора или памяти, и они справлялись с такими «цифрами» очень хорошо, потому что это просто текст.Доказательство того, что 1000000000000 - это не число, а текст: оно может означать 1 триллион (в десятичном виде), 4096 (в двоичном виде) или 281474976710656 (в шестнадцатеричном). Это имеет еще большее значение в разных системах. Значение 1000000000000 - это число, и его сохранение - это отдельная история (мы вернемся к нему чуть позже).
Для хранения текста (в программировании это называется строка ) 1000000000000 вам нужно 14 байтов (по одному на каждый символ плюс завершающий байт NULL, что в основном означает «строка заканчивается здесь»). Это 4 машинных слова. 3 с половиной было бы достаточно, но, как я уже сказал, операции над машинными словами выполняются быстрее всего. Давайте предположим, что ASCII используется для хранения текста, поэтому в памяти это будет выглядеть так: (преобразование ASCII-кодов, соответствующих двоичным
0
и1
двоичным кодам , каждое слово в отдельной строке)Четыре символа умещаются в одно слово, остальные перемещаются в следующее. Остальное перемещается к следующему слову, пока все (включая первый NULL-байт) не уместится.
Теперь вернемся к хранению номеров. Это работает так же, как с переполнением текста, но они располагаются справа налево. Это может показаться сложным, поэтому вот пример. Для простоты предположим, что:
0..9
Вот пустая память из двух слов:
Давайте сохраним номер 4:
Теперь давайте добавим 9:
Обратите внимание, что оба операнда помещаются в один байт, но не результат. Но у нас есть еще один готовый к использованию. Теперь давайте сохраним 99:
Опять же, мы использовали второй байт для хранения числа. Давайте добавим 1:
Упс ... Это называется целочисленным переполнением и является причиной многих серьезных проблем, иногда очень дорогих .
Но если мы ожидаем, что переполнение произойдет, мы можем сделать это:
А теперь добавьте 1:
Это станет понятнее, если вы удалите разделенные байтами пробелы и символы новой строки:
Мы предсказали, что может произойти переполнение, и нам может понадобиться дополнительная память. Таким образом, обработка чисел происходит не так быстро, как с числами, которые помещаются в отдельные слова, и это должно быть реализовано в программном обеспечении. Добавление поддержки 32-битных чисел в 32-битном процессоре фактически делает его 64-битным процессором (теперь он может работать с 64-битными числами изначально, верно?).
Все, что я описал выше, относится и к двоичной памяти с 8-битными байтами и 4-байтовыми словами, это работает примерно так же:
Преобразование таких чисел в десятичную систему довольно сложно. (но это работает довольно хорошо с шестнадцатеричным )
источник
large as the number 1 trillion (1000000000000)
. Кроме того, вы почти говорите об арифметике с произвольной точностью , но вы никогда не упоминаете ни одного из терминов того, что вы говорите ...Вы также можете написать «НАСТОЯЩЕЕ ЗАЯВЛЕНИЕ ЛОЖНО» без сбоя вашего компьютера :) @ Скотт дает точный ответ для определенных платформ вычислений, но ваш вопрос о «написании» большого числа подразумевает, что это просто текст, по крайней мере до это интерпретируется.
Edit: теперь
меньше сарказмаболее полезной информации о различных отношениях число может быть сохранено в памяти. Я буду описывать их с более высокой абстракцией, то есть с точки зрения того, что современный программист может писать код, прежде чем он будет переведен в машинный код для исполнения.Данные на компьютере должны быть ограничены определенным типом , и компьютерное определение такого типа описывает, какие операции могут быть выполнены с этими данными и как (например, сравнивать числа, объединять текст или XOR - логическое значение). Вы не можете просто добавить текст к числу, точно так же, как вы не можете умножить число на текст, поэтому некоторые из этих значений могут быть преобразованы между типами.
Давайте начнем с целых чисел без знака . В этих типах значений все биты используются для хранения информации о цифрах; Ваш пример 32-разрядного целого числа без знака, в котором может храниться любое значение от
0
до2^32-1
. И да, в зависимости от языка или архитектуры используемой платформы вы можете иметь 16-битные или 256-битные целые числа.Что делать, если вы хотите получить негатив? Интуитивно, целые числа со знаком - это название игры. Соглашение состоит в том, чтобы распределять все значения от
-2^(n-1)
до2^(n-1)-1
- таким образом мы избегаем путаницы, когда приходится иметь дело с двумя способами написания+0
и-0
. Таким образом, 32-разрядное целое число со знаком будет содержать значение от-2147483648
до2147483647
. Аккуратно, не правда ли?Хорошо, мы рассмотрели целые числа, которые являются числами без десятичной составляющей. Выразить их сложнее: нецелая часть может быть разумно только где-то между
0
и1
, поэтому каждый дополнительный бит, используемый для ее описания, повысит ее точность: 1/2, 1/4, 1/8 ... Проблема в том, что вы не может точно выразить простое десятичное число0.1
как сумму дробей, у которых в знаменателе могут быть только степени двойки! Разве не было бы намного проще сохранить число как целое число, но согласились бы вместо этого поставить основную (десятичную) точку? Это называется числами с фиксированной запятой , где мы храним,1234100
но договариваемся о соглашении, чтобы читать его как1234.100
вместо.Относительно более распространенный тип, используемый для расчетов
floating point
. То, как это работает, действительно опрятно, он использует один бит для хранения значения знака, а другой - для хранения показателя степени и значения. Существуют стандарты, определяющие такое распределение, но для 32-разрядного числа с плавающей запятой максимальное число, которое вы сможете сохранить, является подавляющимЭто, однако, происходит за счет точности. JavaScript, доступный в браузерах, использует 64-разрядные числа с плавающей запятой, и все еще не может понять все правильно. Просто скопируйте это в адресную строку и нажмите ввод. Оповещение спойлера: результата не будет
0.3
.Есть и другие альтернативные типы, такие как Microsoft .NET 4.5
BigInteger
, которые теоретически не имеют верхних или нижних границ и должны рассчитываться в «пакетах»; но, возможно, более увлекательные технологии - это те, которые понимают математику, например движок Wolfram Mathematica, который может точно работать с абстрактными значениями, такими как бесконечность .источник
Ключ к пониманию того, как компьютеры кодируют числа.
Правда, если компьютер настаивает на хранении чисел с использованием простого двоичного представления числа с использованием одного слова (4 байта в 32-разрядной системе), то 32-разрядный компьютер может хранить только числа до 2 ^ 32. Но есть много других способов кодирования чисел в зависимости от того, чего вы хотите достичь с ними.
Одним из примеров является то, как компьютеры хранят числа с плавающей запятой. Компьютеры могут использовать целую кучу разных способов их кодирования. Стандарт IEEE 754 определяет правила для кодирования чисел больше 2 ^ 32. Грубо говоря, компьютеры могут реализовать это, разделив 32 бита на разные части, представляющие некоторые цифры числа, и другие биты, представляющие размер числа (т. Е. Показатель степени, 10 ^ x). Это позволяет гораздо больший диапазончисел в терминах размера, но ставит под угрозу точность (что хорошо для многих целей). Конечно, компьютер также может использовать более одного слова для этой кодировки, увеличивая точность величины доступных закодированных чисел. Простая десятичная 32-разрядная версия стандарта IEEE допускает числа с точностью до 7 десятичных знаков и числа до 10 ^ 96 по величине.
Но есть много других вариантов, если вам нужна дополнительная точность. Очевидно, что вы можете использовать больше слов в своей кодировке без ограничений (хотя с потерей производительности для преобразования в и из кодированного формата). Если вы хотите изучить один из способов, как это можно сделать, есть отличная надстройка с открытым исходным кодом для Excel, которая использует схему кодирования, позволяющую вычислять сотни цифр точности. Надстройка называется Xnumbers и доступна здесь . Код написан на Visual Basic, который не является самым быстрым из возможных, но имеет то преимущество, что его легко понять и изменить. Это отличный способ узнать, как компьютеры выполняют кодирование более длинных чисел. И вы можете поиграть с результатами в Excel без необходимости установки каких-либо инструментов программирования.
источник
Это все в твоем вопросе.
Вы можете написать любое число на бумаге. Попробуйте написать триллион точек на белом листе бумаги. Это медленно и неэффективно. Вот почему у нас есть десятизначная система для представления этих больших чисел. У нас даже есть имена для больших чисел, таких как «миллион», «триллион» и более, так что вы не говорите
one one one one one one one one one one one...
вслух.32-разрядные процессоры предназначены для наиболее быстрой и эффективной работы с блоками памяти длиной ровно 32 двоичных разряда. Но мы, люди, обычно используем 10-значную цифровую систему, а компьютеры, будучи электронными, используют 2-значную ( двоичную ) систему. Числа 32 и 64 просто имеют степени 2. Так же, как миллион и триллион являются степенями 10. Нам легче работать с этими числами, чем, например, множества 65536.
Мы разбиваем большие числа на цифры, когда пишем их на бумаге. Компьютеры разбивают числа на большее количество цифр. Мы можем записать любое число, которое захотим, как и компьютеры, если мы их спроектируем.
источник
32-битные и 64-битные относятся к адресам памяти. Память вашего компьютера похожа на почтовые ящики, каждый из которых имеет свой адрес. Центральный процессор (центральный процессор) использует эти адреса для адресации областей памяти в вашей оперативной памяти (оперативное запоминающее устройство). Когда процессор мог обрабатывать только 16-битные адреса, вы могли использовать только 32 МБ ОЗУ (что в то время казалось огромным). С 32bit он пошел до 4 + ГБ (который казался огромным в то время). Теперь, когда у нас есть 64-битные адреса, оперативная память переходит в терабайты (что кажется огромным).
Однако программа может выделять несколько блоков памяти для таких вещей, как хранение чисел и текста, что зависит от программы и не связано с размером каждого адреса. Таким образом, программа может сообщить процессору, что я собираюсь использовать 10 адресных блоков памяти, а затем хранить очень большое число, или 10-буквенную строку или что-то еще.
Примечание: адреса памяти указываются «указателями», поэтому 32- и 64-разрядные значения означают размер указателя, используемого для доступа к памяти.
источник
Потому что отображение числа осуществляется с использованием отдельных символов, а не целых чисел. Каждая цифра в номере представлена отдельным символьным литералом, целочисленное значение которого определяется используемой кодировкой, например
'a'
, представлено значением ascii97
, а символом'1'
-49
. Проверьте таблицу ASCII здесь .Для отображения «а» и «1» это то же самое. Это символьные литералы, а не целые числа. Каждый символьный литерал может иметь максимальное значение 255 на 32-битной платформе, сохраняя значение в 8-битном или 1-байтовом размере (это зависит от платформы, однако 8-битный является наиболее распространенным символьным размером), таким образом, они могут быть сгруппированы вместе и могут быть отображается. Сколько отдельных символов они могут отображать, зависит от вашей оперативной памяти. Если у вас есть только 1 байт ОЗУ, вы можете отобразить только один символ, если у вас есть 1 ГБ ОЗУ, вы можете хорошо отобразить 1024 * 1024 * 1024 символа (слишком лениво, чтобы делать математику).
Это ограничение, однако, относится к вычислениям, однако, я думаю, вы заинтересованы в стандарте IPV4. Хотя это не совсем связано с компьютерами
bit-size
Это как-то повлияло на стандарты. При создании стандарта IPV4 они сохраняли значения ip в 32-разрядных целых числах. Теперь, когда вы дали размер, он стал стандартным. Все, что мы знаем об Интернете, зависело от этого, и затем у нас закончились IP-адреса для назначения. Поэтому, если стандарт IP был пересмотрен на 64-битный, все просто перестанет работать, включая ваш маршрутизатор (я полагаю, это правильно) и другие сетевые устройства. Таким образом, должен быть создан новый стандарт, который просто поменял 32-битное целое на 128-битное. И скорректированы остальные стандартные. Производителю оборудования просто нужно заявить, что он поддерживает этот новый стандарт, и он станет вирусным. Хотя это не так просто, но я думаю, вы поняли это здесь.Отказ от ответственности: большинство пунктов, упомянутых здесь, соответствуют моему предположению. Возможно, я упустил важные моменты, чтобы упростить его. Я не очень хорошо разбираюсь в цифрах, поэтому, должно быть, пропустил некоторые цифры, но я хочу ответить на вопрос ОП о том, почему он не сломает ПК.
источник
1
0x31 в ASCII, а не 0x1. 1 ГБ = 1024 ^ 3 B. IPv4 был изобретен до того, как были введены 32-разрядные ЦП, поэтому утверждение о том, что адреса хранятся в 32-разрядных целых числах, противоречит вопросу OP. И наконец, IPv6 использует 128-битные адреса, а не 64-битные.В процессорах есть «слова». Есть разные слова. Когда люди говорят «32-битный процессор», они в основном имеют в виду «ширину шины памяти». Это слово состоит из различных «полей», которые относятся к подсистемам компьютера, соответствующим передаче (24 бита) и управлению (другие биты). Я могу ошибаться насчет точных цифр, убедитесь в этом в руководствах.
Совершенно другой аспект - это вычисления. Наборы инструкций SSE и MMX могут хранить длинные целые числа. Максимальная длина без потери производительности зависит от текущей версии SSE, но она всегда кратна 64 битам.
Современные процессоры Opteron могут обрабатывать числа шириной 256 бит (я не уверен насчет целых чисел, но float точно).
Резюме : (1) ширина шины не связана напрямую с шириной вычислений, (2) даже разные слова (слово памяти, слово регистра, слово шины и т. Д.) Не связаны друг с другом, в противном случае они имеют общий делитель около 8 или 16 или 24. Многие процессоры даже использовали 6-битное слово (но его история).
источник
Назначение вычислительного устройства, как правило, состоит в том, чтобы принимать, обрабатывать, хранить и передавать данные. Базовое оборудование - это просто машина, которая помогает выполнять эти четыре функции. Это не может сделать ни один из тех без программного обеспечения.
Программное обеспечение - это код, который сообщает машине, как принимать данные, как их обрабатывать, как их хранить и как предоставлять их другим.
Базовое оборудование всегда будет иметь ограничения. В случае 32-битной машины большинство регистров, обрабатывающих данные, имеют ширину всего 32 бита. Это не означает, однако, что машина не может обрабатывать числа, превышающие 2 ^ 32, это означает, что если вы хотите работать с большими числами, машина может принять более одного цикла, чтобы принять его, обработать его, сохранить это или испустить это.
Программное обеспечение сообщает машине, как обрабатывать числа. Если программное обеспечение предназначено для обработки больших чисел, оно отправляет в ЦПУ серию инструкций, которые сообщают ему, как обрабатывать большие числа. Например, ваш номер может быть представлен двумя 32-битными регистрами. Если вы хотите добавить 1,234 к вашему номеру, программа скажет ЦПУ сначала добавить 1,234 к нижнему регистру, а затем проверить бит переполнения, чтобы увидеть, не привело ли это добавление к слишком большому числу для нижнего регистра. Если это так, то он добавляет 1 в верхний регистр.
Точно так же, как начальных школьников учат складывать с переносом, ЦПУ можно указывать обрабатывать числа больше, чем он может хранить в одном регистре. Это верно для большинства общих математических операций, для чисел любого практического размера.
источник
Разница заключается в том, как мы храним данные на компьютерах.
Вы правы, что для теоретической 8-битной машины мы можем хранить только 2 ^ 8 значений в одном регистре процессора или в памяти. (Пожалуйста, имейте в виду, что это зависит от "машины" до "машины" в зависимости от используемого процессора, архитектуры памяти и т. Д. Но пока давайте придерживаться гипотетической "стереотипной" машины.)
Для теоретического 16-разрядного компьютера максимальное значение в регистре / ячейке памяти будет равно 2 ^ 16, для 32-разрядного компьютера, 2 ^ 32 и т. Д.
На протяжении многих лет программисты изобрели все виды chicanery для хранения и обработки чисел, больших, чем можно хранить в одном регистре процессора или в памяти. Существует много методов, но все они включают использование более одного адреса регистра / памяти для хранения значений, превышающих ширину их «родного» регистра / области памяти.
Все эти методы полезны тем, что машина может хранить / обрабатывать значения, превышающие их исходную емкость. Недостатком является то, что почти все подходы требуют нескольких машинных инструкций / чтений / и т.д. обрабатывать эти цифры. Для случайного большого количества это не проблема. При работе с большим количеством больших чисел (в частности, с большими адресами памяти) накладные расходы замедляют работу.
Отсюда общее желание сделать регистры, ячейки памяти и аппаратные адреса памяти «шире» и шире, чтобы обрабатывать большие числа «изначально», чтобы такие числа можно было обрабатывать с минимальным количеством операций.
Поскольку размер числа бесконечен, регистр процессора / размер памяти / адресация всегда является балансом размера собственного числа и затрат, связанных с внедрением все большей и большей ширины.
источник
32-битные компьютеры могут хранить числа до 2 ^ 32 в одном машинном слове, но это не значит, что они не могут обрабатывать большие объекты данных.
Смысл 32-битного компьютера, как правило, заключается в том, что шина данных и адресная шина имеют ширину 32 бита, что означает, что компьютер может одновременно обрабатывать 4 ГБ адресного пространства памяти и одновременно отправлять четыре байта данных по шине данных. ,
Это, однако, не ограничивает компьютер в обработке большего количества данных, ему просто нужно разделить данные на четыре байта, когда они отправляются по шине данных.
Обычный 32-разрядный процессор Intel может обрабатывать 128-разрядные числа внутри страны, что позволяет без проблем обрабатывать такие числа, как 100000000000000000000000000000000000000.
Вы можете обрабатывать намного большие числа, чем в компьютере, но тогда вычисления должны выполняться с помощью программного обеспечения, у ЦПУ нет инструкций для обработки чисел, превышающих 128 бит. (Он может обрабатывать гораздо большее число в виде чисел с плавающей запятой, но тогда у вас будет только 15 цифр точности.)
источник
Просто добавив примечание ко многим другим ответам, потому что это довольно важный факт в этом вопросе, который был упущен.
«32 бита» относится к ширине адреса памяти. Это не имеет никакого отношения к размеру регистра. Многие 32-битные процессоры, вероятно, имеют 64 или даже 128-битные регистры. В частности, что касается линейки продуктов x86, последние потребительские ЦП, которые являются 64-битными, имеют до 256-битных регистров для специальных целей.
Эта разница между шириной регистра и шириной адреса существовала с древних времен, когда у нас было 4-битные регистры и 8-битные адреса, или наоборот.
Легко видеть, что сохранение большого числа не является проблемой независимо от размера регистра, как объяснено в других ответах.
Причина, по которой регистры, какого бы размера они ни были, могут также рассчитываться с большими числами, заключается в том, что слишком большие вычисления могут быть разбиты на несколько меньших, которые вписываются в регистры (это просто немного сложнее в действительности).
источник
Ответы, которые уже даны, на самом деле довольно хороши, но они имеют тенденцию решать проблему с разных сторон и, таким образом, представляют неполную картину. Они также немного излишне технические, по моему мнению.
Итак, просто чтобы прояснить то, на что намекают, но явно не выражены ни в одном из других ответов, и что, я думаю, является сутью вопроса:
Вы смешиваете несколько понятий в своем вопросе , и одно из них («32 бита») может фактически относиться к множеству разных вещей (и разные ответы предполагают разные интерпретации). Все эти понятия имеют какое-то отношение к числу битов (1 и 0), используемых (или доступных) в различных вычислительных контекстах (что я имею в виду под этим, я надеюсь, будет разъяснено в приведенных ниже примерах), но в остальном понятия не связаны .
Явное:
Обратите внимание, что это не является исчерпывающим списком толкований фразы «32 бита».
Дополнительный кредит: чтобы действительно увидеть философское различие между числами и примитивными кусками компьютерной памяти, прочитайте немного о машинах Тьюринга .
источник
Если вы напишите 1000000000000, например, в калькуляторе, компьютер вычислит его как вещественное число с десятичной точкой . Упомянутый вами предел для 32-х бит больше касается всех чисел типа Integer без десятичной точки. Разные типы данных используют разные методы, как попасть в биты / байты.
Целочисленные номера типов : эта таблица может помочь вам понять суть ( http://msdn.microsoft.com/en-us/library/296az74e.aspx ). Это касается ограничений для C ++. Например, номер типа Int64 имеет ограничения от -9223372036854775808 до 9223372036854775807.
Числа действительного типа : числа действительного типа содержат значение с плавающей запятой и показателем степени, и вы можете вводить намного большие числа, но с ограниченной точностью. ( http://msdn.microsoft.com/en-us/library/6bs3y5ya.aspx ) Например, LDBL (большой двойной) в C ++ имеет максимальный показатель 308, так что, возможно, вы можете ввести или иметь в результате число
9.999 x 10^308
, значит, вы будете теоретически иметь 308 (+1) цифр,9
но для его представления будут использоваться только 15 самых важных цифр, остальные будут потеряны, причина ограниченной точности.Кроме того, существуют разные языки программирования, и они могут иметь разные реализации ограничений по количеству. Таким образом, вы можете представить, что специализированные приложения могут обрабатывать гораздо большие (и / или более точные / точные) числа, чем C ++.
источник
Если вам нужен практический пример того, как много программ в типичной системе Linux обрабатывают и выводят большое количество данных:
libgmp
- Многофункциональная арифметическая библиотека GNU является наиболее широко используемой библиотекой для этой цели в системах Linux. Простой пример умножения 2 ^ 80 на 1000:Таким образом, в основном это то же самое, что и обычные операторы + - * /, просто с библиотекой, которая разбивает числа и сохраняет их внутри как числа, состоящие из нескольких машинных слов (то есть 32-битных). Существуют также функции типа scanf () для обработки преобразования текста в целочисленные типы.
Структура
mpz_t
точно такая же, как у Скотта Чемберлена, когда он считает до 6 двумя руками. В основном это массив типов машинных словmp_limb_t
, и когда число слишком велико, чтобы вписать машинное слово, GMP использует несколькоmp_limb_t
для хранения старших / младших частей числа.источник
В вашем уме вы знаете только 10 разных цифр. От 0 до 9. Внутри вашего мозга это, конечно, кодируется иначе, чем в компьютере.
Компьютер использует биты для кодирования чисел, но это не важно. Именно так инженеры решили кодировать вещи, но вы должны это игнорировать. Вы можете представить себе, что 32-битный компьютер имеет уникальное представление из более чем 4 миллиардов различных значений, в то время как мы, люди, имеем уникальное представление для 10 различных значений.
Всякий раз, когда мы должны постичь большее число, мы используем систему. Самый левый номер - самый важный. Это в 10 раз важнее следующего.
Компьютер, способный различать четыре миллиарда различных значений, также должен будет сделать крайнее левое значение в наборе значений в четыре миллиарда раз более важным, чем следующее значение в этом наборе. На самом деле компьютер не заботится вообще. Это не присваивает «важность» числам. Программисты должны сделать специальный код, чтобы позаботиться об этом.
Всякий раз, когда значение становится больше числа уникальных символов, 9 в человеческом уме, вы добавляете его к числу слева.
В этом случае номер по-прежнему вписывается в один «слот»
Поэтому люди всегда сталкиваются с проблемой нехватки уникальных символов. Если компьютер не имеет системы, чтобы справиться с этим, он просто напишет 0, забыв, что было дополнительное число. К счастью, компьютеры имеют «флаг переполнения», который поднимается в этом случае.
Возможно, вы изучили метод в школе. Алгоритм Алгоритм довольно прост. Начните с добавления двух крайних левых символов.
Затем вы переходите к следующему слоту и выполняете такое же дополнение.
Поскольку у нас было переполнение, это означает, что мы должны добавить 1 к следующему числу.
Больше нет номеров, которые нужно добавить, поэтому мы просто создаем слот и вставляем 1, потому что флаг переполнения был поднят.
Компьютер делает это точно так же, за исключением того, что он имеет 2 ^ 32 или даже лучше 2 ^ 64 различных символов, а не только 10, как люди.
На аппаратном уровне компьютер работает с одиночными битами, используя один и тот же метод. К счастью, это абстракция для программистов. Биты только две цифры, потому что это легко представить в линии электропередачи. Либо свет включен, либо выключен.
Наконец, компьютер может отображать любое число в виде простой последовательности символов. Это то, что компьютеры лучше всего. Алгоритм преобразования между последовательностью символов и внутренним представлением довольно сложен.
источник
Потому что вы отображаете не число (насколько это касается компьютера), а строку или последовательность цифр. Конечно, некоторые приложения (вроде калькулятора, я полагаю), которые имеют дело с числами, могут обрабатывать такое число, я думаю. Я не знаю, какие уловки они используют ... Я уверен, что некоторые другие, более сложные ответы охватывают это.
источник
Большая часть содержания этого ответа первоначально была получена из этого ответа (написанного до того, как этот другой вопрос был помечен как дубликат). Поэтому я обсуждаю использование 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 xxxx xxxx xxxx xxxx 1101 0111
aka:
0x4082xxxxD7
Теперь позвольте мне интерпретировать это для вас:
0x означает, что следующие цифры являются шестнадцатеричными.
Я буду обсуждать "40" более подробно в ближайшее время.
82 является частью регистра «A», который представляет собой последовательность из 8 битов.
xx и xx являются частью двух других регистров, называемых регистром «B» и регистром «C». Причина, по которой я не заполнил эти биты нулями или единицами, состоит в том, что инструкция «ДОБАВИТЬ» (отправленная в ЦП) может привести к тому, что эти биты не изменятся инструкцией (тогда как большинство других битов, которые я использую в этом примере, может изменить, за исключением некоторых битов флага).
D7 поместится в большем количестве битов, называемых регистром «D».
Регистр это просто кусок памяти. Регистры встроены в ЦП, поэтому ЦП может обращаться к регистрам без необходимости взаимодействия с памятью на карте памяти.
Таким образом, математический результат 0xA5 умножить на 0xCB равен 0x82D7.
Теперь, почему биты были разделены на регистры A и D вместо регистров A и B или регистров C и D? Ну, еще раз, это пример сценария, который я использую, и он должен быть похож на концепцию реального языка ассемблера (16-битный Intel x86, используемый в Intel 8080 и 8088 и многих новых процессорах). Могут существовать некоторые общие правила, такие как регистр «C», обычно используемый в качестве индекса для операций подсчета (типичный для циклов), и регистр «B», используемый для отслеживания смещений, которые помогают указывать области памяти. Таким образом, «А» и «D» могут быть более распространенными для некоторых общих арифметических функций.
Каждая инструкция CPU должна иметь некоторую документацию, используемую людьми, которые программируют на ассемблере. В этой документации должно быть указано, какие регистры используются каждой инструкцией. (Таким образом, выбор используемых регистров часто определяется разработчиками ЦП, а не программистами на языке ассемблера. Хотя может быть некоторая гибкость.)
Теперь вернемся к «40» в приведенном выше примере: это серия битов, часто называемая «регистром флагов». Каждый бит в регистре флагов имеет имя. Например, есть бит «переполнения», который может установить процессор, если полученный результат больше, чем пространство, в котором может храниться один байт результатов. (Бит «переполнение» часто может называться сокращенным именем «OF». Это заглавная буква o, а не ноль.) Программное обеспечение может проверить значение этого флага и заметить «проблему». Работа с этим битом часто незаметно обрабатывается языками более высокого уровня, поэтому начинающие программисты часто не узнают о том, как взаимодействовать с флагами процессора. Однако программисты на ассемблере могут обычно обращаться к некоторым из этих флагов способом, очень похожим на другие переменные.
Например, у вас может быть несколько инструкций 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-битным процессором».
источник