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


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

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

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


365


Источник


Этот вопрос ошибочен. 32-разрядные машины могут обрабатывать числа, намного превышающие 2 ^ 32. Они делают это все время, с «длинными» и так далее. Они могут хранить до 2 ^ 32 в одном регистре, но программное обеспечение записывается для обхода этой проблемы. Некоторые современные языки даже не имеют проблемы с длиной заданного числа. - JFA
Пожалуйста, оставляйте комментарии по темам, вежливым и соответствующим техническим аспектам вопроса. Почти 50 шуток уже нужно было удалить, и нам бы хотелось избежать блокировки сообщения. Спасибо. - nhinkle♦
Этот вопрос написан таким образом, что он немного неряшлив. Что вы подразумеваете под словом «написать» и «отобразить» номер 1000000000000? Когда вы написали вопрос, вы написали номер 1000000000000, и ваш веб-браузер отображает его просто отлично, я предполагаю, но это не должно быть ничем странным для тех, кто когда-либо использовал компьютер раньше. Вопрос требует бесплатной интерпретации. - HelloGoodbye
По оценкам, человеческое сознание вмещает около 50 бит (я где-то читал). Поэтому вопрос не в том, «Как я могу написать 10^9 без моего компьютера рушится? ", а скорее" Как я могу написать 10^(18) без моего мозга, разбившегося? " - Hagen von Eitzen
32-разрядные компьютеры могут хранить только целые числа UNSIGNED до 2 ^ 32 - 1. 2 ^ 32 - 1 даже не равны 2,147,483,647 ... 300 голосов, и никто не понял этого? - Koray Tugay


Ответы:


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

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

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


785



Смешно, @codename. Как тогда вы рассчитываете на свои пальцы до 32 или более (т. Е. Когда 2 ^ 5 исчерпан)? ;) Аналогия перехода на другую руку хороша ... даже если бинарный задерживает необходимость переходить к другой руке. Что бы я хотел видеть составляет до 1024 или более, с ловкостью педали, чтобы переместиться на ноги для дальнейшего подсчета в двоичном формате - до 1 048 575! :) Это потенциально 20-разрядная мощность дочерней платы. :П - J0e3gan
Пожалуйста, оставляйте комментарии по теме и уместны для обсуждения технических аспектов этого ответа. Более 60 шуток уже были удалены из этого ответа, и мы бы хотели избежать блокировки сообщения. - nhinkle♦
@ codename- easy, вы назначаете один палец в качестве указателя стека. Как только вы закончите пальцы, вы добавите сумму в стек и перезапустите подсчет. - Makach
Откуда вы это узнали, @codename? Я впервые услышал это от Фредерика Поля, см., Например, Вот hjkeen.net/halqn/f_pohl3.htm - Zane
Я думаю, что это не ответ на соответствующий вопрос. Ответ @ Bigbio2002 правильный. Здесь «1000000000000» - это не номер, а текст, как «adsfjhekgnoregrebgoregnkevnregj». То, что вы говорите, верно, но я твердо чувствую, что это не правильный ответ. И увидеть так много upvotes ... - Master Chief


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

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


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

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


397



На самом деле это в основном правильное, но не совсем. 32-разрядный номер с плавающей запятой вряд ли сможет точно представлять 1000000000000. Он будет представлять собой номер очень очень близко к желаемому номеру, но не точно. - Tim B
@TimB: Вы слышали о формате decimal32? Это часть стандарта IEEE 754-2008. Этот формат способен корректно отображать этот номер :) - V-X
Правда, это может быть. Однако это не тот формат, который люди имеют в виду, когда говорят «float», что обычно относится к 32-битовому числу с плавающей запятой, которое хранится и используется стандартными процессорами с плавающей запятой в текущих компьютерах. - Tim B
@TimB действительно. Ближайшим номером к тому, что может быть представлено как float32, является 999999995904 - greggo
@TimB: Но 64-разрядное число с плавающей запятой может легко представлять 1000000000000 в точку. Это 10 ^ 12, или 2 ^ 12 * 5 ^ 12; 5 ^ 12 требует 28 бит мантиссы. - Keith Thompson


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

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

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

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

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

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

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

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

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

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


189



Ваш ответ читается довольно снисходительно. OP явно говорит о номере, а не о тексте: large as the number 1 trillion (1000000000000), Кроме того, вы почти говорите о Арифметика с произвольной точностью, но вы никогда не упоминаете ни слова о том, что вы говорите .... - MirroredFate
«1 трлн» - это также строка - Elzo Valugi
@ElzoValugi Это. Мне пришлось найти способ представить понятие абстрактного числа, в отличие от строки, представляющей число. Я считаю, что «1 триллион» - это лучший и менее двусмысленный способ сделать это (см. Доказательство в ответ). - gronostaj
@MirroredFate Я не согласен с тем, что «явно говорит о числе». OP говорит «отображается отлично», что ясно является говоря о тексте «1000000000000» мне ... - Joe
@yannbane 'A' - символ, а не число. '?' является символом, а не числом. «1» - это символ, а не число. Символы - это просто символы. Они могут представлять цифры или цифры, но определенно они не являются цифрами. «1» может стоять на одну, десять, сто, тысячу и т. Д., Это просто символ, обозначающий цифру, которая может быть числом или ее частью. «10» (строка символов) может означать два или восемь или десять или шестнадцать и т. Д., Но когда вы говорите, что у вас десять яблок, вы используете десятку, и все знают, что вы имеете в виду. Существует огромная разница между символами и цифрами. - gronostaj


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

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

Данные на компьютере должны быть ограничены определенным тип, а компьютерное определение такого типа описывает, какие операции могут выполняться над этими данными и как (например, сравнивать числа, конкатенатировать текст или 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-битный плавающий максимальное количество, которое вы могли бы сохранить, является подавляющим

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

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

javascript:alert(0.1+0.2);

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


40



Вы можете сделать это в это реальность. Попробуйте сделать это в Вселенной Star Trek. Просто отступите назад, из-за всех искр и дыма. - Michael Petrotta
Это не совсем так, как работает фиксированная точка. На самом деле это система, где числа масштабируются и смещаются для создания десятичной точки. В вашем примере масштаб равен 1/1000, но есть также номера фиксированной точки (особенно в компьютерной графике): 0 = 0.0, 255 = 1.0 - шкала равна 1/255. - Andon M. Coleman


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

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

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

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


31





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

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

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

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


24





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



15



Хороший ответ, за исключением деталей - 16 битов адресного пространства дали вам 64 кб, а не 32 Мб, а машины, такие как 286, имели 24-битные адреса (для 16 МБ). Кроме того, с 64-разрядными адресами вы выходите далеко за пределы терабайт - больше, чем у 16 ​​экзабайт - терабайты - это те ограничения, на которые накладываются материнские платы / процессоры нынешнего поколения, а не размер адресов. - Phil
32-бит относится к размеру машинного слова, а не к адресам памяти. Как отметил Фил, 286 был 16-битным процессором, но использовал 24 бита для адресации через сегментацию памяти. Процессоры x86 являются 32-разрядными, но используют 36-разрядную адресацию. Видеть PAE, - gronostaj
@gronostaj хорошо x86 имеют 32-битную адресацию от 386 до Pentium. - Ruslan
Upvote, потому что это единственный ПРАВИЛЬНЫЙ ответ здесь - 32-разрядный относится к 32-битной адресации памяти, а не к 32-разрядной арифметике. - user1207217
@ user1207217: ?? Итак, согласно вашим аргументам, например, Z80 или 8080 являются 16-разрядными процессорами (из-за 16-разрядной адресации памяти и шины памяти)? - pabouk


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

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

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


13



Я не замедлен, но есть ряд проблем с вашим ответом. 1 0x31 в ASCII, а не 0x1. 1 GB = 1024 ^ 3 B. IPv4-накопитель, изобретенный до того, как были введены 32-битные процессоры, поэтому заявка, что адреса были сохранены в 32-битных целых числах, противоречит вопросу OP. И, наконец, IPv6 использует 128-битные адреса, а не 64-разрядные. - gronostaj


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

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

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

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


12



Неправда, оригинальный процессор Pentium имел 64-битную шину данных для высокой пропускной способности памяти, хотя это был 32-разрядный процессор. 8088 был 16-разрядным процессором с 8-битной шиной данных. - doug65536