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

32-разрядные компьютеры могут хранить только целые числа со знаком до 2 31 - 1.
Вот почему у нас закончились адреса IPv4 и они вошли в 64-разрядную эру.

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

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

366 голосов | спросил 5 revs, 4 users 53%
Ben Johnson mk2
1 Jam1000000amThu, 01 Jan 1970 03:00:00 +030070 1970, 03:00:00

19 ответов


786

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

  

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

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
397

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

В буквальном отображении число «1000000000000» требует 13 байт памяти. Каждый отдельный байт может содержать значение до 255. Ни одно из них не может содержать целое числовое значение, но интерпретируется индивидуально как символы ASCII (например, символ «0» представлен десятичным значением 48, двоичное значение 00110000), их можно объединить в формат, который имеет смысл для вас, человека.


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

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
189

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

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

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

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

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

Чтобы сохранить текст (в программировании он называется string ) 1000000000000 вам нужно 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

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

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

Преобразование таких чисел в десятичную систему сложнее. (но он работает очень хорошо с шестнадцатеричным )

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
40

Вы также можете написать «ЭТО ЗАЯВЛЕНИЕ ЛОЖНО» без сбоя компьютера :) @ Ответ Скотта определен для определенных рамок расчета, но ваш вопрос о «написании» большого количества подразумевает, что это просто текст, по крайней мере до тех пор, пока он не будет интерпретироваться.

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

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

Начнем с целых чисел без знака . В этих типах значений все биты используются для хранения информации о цифрах; ваш пример представляет собой 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-битного float максимальное число, которое вы могли бы сохранить, является подавляющим

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

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

javascript:alert(0.1+0.2);

Существует больше альтернативных типов, таких как Microsoft .NET 4.5 BigInteger , который теоретически не имеет верхних или нижних границ и должен быть рассчитан в «партиях»; но, возможно, более увлекательными являются технологии, которые понимают математику, такую ​​как движок Wolfram Mathematica, который может точно работать с абстрактными значениями, такими как бесконечность .

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
31

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

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

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

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
24

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

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

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

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
15

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
13

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

Однако это ограничение относится к вычислениям, однако, я думаю, вас интересует стандарт IPV4. Хотя это не полностью связано с размером bit-size

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
12

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

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

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

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
10

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

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

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

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

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
10

Разница заключается в том, как мы храним данные на компьютерах.

Вы правы, что для теоретической 8-разрядной машины мы можем хранить только значения 2 ^ 8 в регистре одного процессора или в памяти. (Пожалуйста, имейте в виду, что это варьируется от «машины» до «машины» на основе используемого процессора, архитектуры памяти и т. Д. Но на данный момент давайте придерживаться гипотетической машины «стереотипа».)

Для теоретической 16-разрядной машины максимальное значение в регистре /ячейке памяти будет равно 2 ^ 16 для 32-разрядной машины, 2 ^ 32 и т. д.

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

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

Следовательно, общее стремление сделать регистры, ячейки памяти и аппаратные средства адресной памяти «шире» и шире, чтобы обрабатывать большие числа «изначально», поэтому такие числа могут обрабатываться с минимальным количеством операций.

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
8

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

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

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

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

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
6

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

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

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

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

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
6

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

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

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

Явное:

  • «IPv4 /6» относится к интернет-протоколу , своду правил, определяющих, как информация должен быть упакован и интерпретирован в Интернете. Первичное (или, по крайней мере, самое известное) различие между IPv4 и IPv6 состоит в том, что адресное пространство (т. Е. Набор адресов, которые можно использовать для различения между различными местоположениями в сети) больше в IPv6. Это связано с тем, сколько бит в каждом пакете данных, отправленных по сети, выделено для (то есть для целей), идентифицирующих отправителя пакета и предполагаемого получателя.
    • Не-вычислительная аналогия: каждый пакет похож на письмо, отправленное через уличную почту, а адресное пространство похоже на количество символов, которые вы разрешаете использовать при написании адреса и обратного адреса на конверте.
    • Я пока не вижу этого в любом из других ответов.
  • Слово «память» в памяти компьютера (32-разрядная и 64-разрядная) обычно можно рассматривать как самую маленькую часть данных, которую использует компьютер, или «думает». Эти биты данных объединяются, чтобы составить другой биты данных, такие как фрагменты текста или большие целые числа.
    • Не-вычислительная аналогия: слова можно рассматривать как буквы, составляющие слова на бумаге, или даже как отдельные слова в процессе мысли.
    • См. ответ Гуффа , sanaris и первый абзац ответа gronostaj .
  • 32-разрядные указатели могут быть или не быть словами, но тем не менее они обрабатываются атомарно (то есть как отдельные единицы, которые нельзя разбить на более мелкие компоненты). Указатели - это самый низкий уровень, на котором компьютер может записывать местоположение в памяти некоторого произвольного фрагмента данных. Обратите внимание, что размер указателя, используемый компьютером (или, действительно, операционной системой), ограничивает диапазон памяти, к которому может обращаться один указатель, так как существует только столько возможных мест памяти, на которые указатель может «указывать» на так как есть возможные значения для самого указателя. Это аналогично тому, как IPv4 ограничивает диапазон возможных интернет-адресов, но not ограничивает объем данных, которые могут присутствовать, например, на определенной веб-странице. Однако размер указателя not ограничивает размер самих данных, на которые указывает указатель. (Пример схемы, позволяющей размеру данных превышать диапазон указателей, ознакомьтесь с структурой указателей inode Обратите внимание, что это немного другое использование слова «указатель», чем обычно, поскольку указатель обычно ссылается на указатель на случайную доступную память, а не на место на жестком диске.)
    • Не-вычислительная аналогия: хмммм .... это немного сложно. Возможно, десятичная система Дьюи для индексирования библиотечных материалов немного похожа? Или любая система индексирования, действительно.
    • См. ответ SiteNook .
    • Обратите внимание, что мое объяснение указателей выше дает некоторые тонкие детали и, возможно, не совсем корректно. Однако в языках программирования, в которых программисты работают напрямую с указателями, ментальный режим, который я нарисовал, обычно достаточен для практических целей.
  • Номера , которые компьютер «способен отображать» , не являются (для практических целей) ограниченными аппаратным или операционным системами компьютера; они рассматриваются как любой другой текст.

Обратите внимание, что это не является исчерпывающим списком интерпретаций для фразы «32 бит».

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
5

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

Целочисленные номера типов : Эта таблица поможет вам уловить точку ( 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 ++.

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
5

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

libgmp - Библиотека многоточечной арифметики GNU - наиболее широко используемая библиотека для этой цели в системах 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 похожа на пример Скотта Чемберлена с подсчетом 6, используя две руки. В основном это массив машинных слов размером mp_limb_t, а когда число слишком велико, чтобы соответствовать машинным словам, GMP использует несколько mp_limb_t для хранения высоких /низких частей от числа.

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
5

В вашем уме вы знаете только 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, как люди.

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

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
3

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

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05
0

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

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

Теперь вы можете предположить, что 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
a.k.a .:
0x4082xxxxD7
Теперь позвольте мне интерпретировать это для вас:
0x просто означает, что следующие цифры являются шестнадцатеричными.
Я буду обсуждать «40» более подробно на мгновение.
82 является частью регистра «A», который представляет собой серию из 8 бит.
xx и xx являются частью двух других регистров, называемых регистром «B» и регистром «C». Причина, по которой я не заполнял эти биты нулями или единицами, заключается в том, что команда «ADD» (отправленная в CPU) может привести к тому, что эти биты не будут изменены инструкцией (тогда как большинство других битов, которые я использую в этом примере, могут получить изменение, за исключением некоторых битов флага).
D7 будет вписываться в большее количество бит, называемый регистром «D».
Регистр - это всего лишь часть памяти. Регистры встроены в ЦП, поэтому ЦПУ может обращаться к регистрам без необходимости взаимодействовать с памятью на палке RAM.

Итак, математический результат 0xA5 раз 0xCB равен 0x82D7.

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

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

Теперь вернемся к «40» в приведенном выше примере: это серия бит, которую часто называют «регистром флагов». Каждый бит в регистре флагов имеет имя. Например, есть бит «переполнения», который может установить ЦП, если итоговое значение больше, чем пространство, которое может хранить один байт результатов. (Бит «переполнения» часто может упоминаться сокращенным названием «OF». Это капитал o, а не ноль.) Программное обеспечение может проверить значение этого флага и заметить «проблему». Работа с этим битом часто обрабатывается невидимыми языками более высокого уровня, поэтому начинающие программисты часто не узнают о том, как взаимодействовать с флагами CPU. Тем не менее, программисты Ассамблеи могут обычно обращаться к некоторым из этих флагов таким образом, который очень похож на другие переменные.

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

(Обычно также имеется флаг «underflow», если вы вычтите слишком много, чтобы соответствовать желаемому результату.)

Просто чтобы показать вам, как получилось сложное:
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-разрядным ЦП».

ответил user566245 7 52014vEurope/Moscow11bEurope/MoscowFri, 07 Nov 2014 18:39:05 +0300 2014, 18:39:05

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132