題 如果32位機器只能處理高達2 ^ 32的數字,為什麼我可以在沒有機器崩潰的情況下寫入1000000000000(萬億)?


32位計算機只能存儲最多2個有符號整數31  - 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 up-votes並且沒有人意識到這一點? - Koray Tugay


答案:


我通過問你一個不同的問題回答你的問題:

你怎麼指望你的手指?

你可能只用一隻手就可以計算到最大可能的數字,然後當你的手指用盡時你會轉到你的第二隻手。計算機做同樣的事情,如果他們需要表示一個大於單個寄存器可以容納的值,他們將使用多個32位塊來處理數據。


785



好笑,@代號。那麼你如何指望你的手指達到32或更多(即一旦2 ^ 5耗盡)? ;)移動到另一隻手的類比是好的......即使二進制延遲了移動到另一隻手的需要。 我想看到什麼 用手指靈巧計數到1,024或更多,以便進一步計算二進制數 - 高達1,048,575! :)這可能是20位的子板電源。 :P - J0e3gan
請保留關於主題的評論,並與討論此答案的技術方面相關。 已經從這個答案中刪除了60多個笑話評論,我們希望避免鎖定帖子。 - nhinkle♦
@ codename- easy,你將一個手指指定為堆棧指針。一旦手指耗盡,就可以將金額添加到堆棧並重新開始計數。 - Makach
你在哪裡知道的,@代號?我首先從Frederik Pohl那裡聽到了這一點,例如,這裡 hjkeen.net/halqn/f_pohl3.htm - Zane
我認為這不是相關問題的答案。回答@ Bigbio2002是正確的。這裡“1000000000000”不是數字而是文本,就像“adsfjhekgnoregrebgoregnkevnregj”。你說的是真的,但我強烈認為這不是正確的答案。看到這麼多的讚成...... - Master Chief


你是正確的,32位整數不能容納大於2 ^ 32-1的值。但是,這個32位整數的值以及它在屏幕上的顯示方式是兩個完全不同的東西。打印的字符串“1000000000000”不由內存中的32位整數表示。

要字面上顯示數字“1000000000000”需要13個字節的內存。每個字節可以保存最多255個值。它們都不能保存整個數值,但可​​以單獨解釋為ASCII字符(例如,字符'0'由十進制值48表示,二進制值 00110000),它們可以串聯成一種對你有意義的格式。


編程中的一個相關概念是 類型轉換,這是計算機將如何解釋特定的流 0s和 1秒。如上例所示,它可以被解釋為數值,字符,甚至完全不是其他東西。雖然32位整數可能無法保存值1000000000000,但使用完全不同的解釋時,32位浮點數將能夠。

至於計算機如何在內部使用和處理大數字,存在64位整數(可以容納高達1600億億的值),浮點值,以及可以任意大的工作的專用庫數字。


398



實際上這大多是正確但不完全。 32點浮點數不太可能準確地表示1000000000000.它將表示非常接近所需數字的數字,但不完全相同。 - Tim B
@TimB:你聽說過decimal32格式嗎?它是IEEE 754-2008標準的一部分。這種格式能夠正確表示這個數字:) - V-X
沒錯,那可以。然而,當他們說“浮動”時,這並不是人們所說的格式,浮動通常指的是當前計算機中標準浮點處理器存儲和使用的32位浮點數。 - Tim B
@TimB確實。可以表示為float32的最接近的數字是999999995904 - greggo
@TimB:但是64位浮點數很容易表示 1000000000000 究竟。它是10 ^ 12,或2 ^ 12 * 5 ^ 12; 5 ^ 12需要28位尾數。 - Keith Thompson


首先,32位計算機可以存儲高達2³²-1的數字 在一個單一的機器字機器字 是CPU可以以自然方式處理的數據量(即,對該大小的數據的操作在硬件中實現並且通常最快地執行)。 32位CPU使用由32位組成的字,因此它們可以存儲0到2³²-1之間的數字 總而言之

第二, 1萬億 和 萬億 是兩件不同的事情。

  • 1萬億是數字的抽象概念
  • 1000000000000是文本

按下 1 一次又一次 0 12次你輸入文字。 1 輸入 10 輸入 0。看到?你正在輸入字符。字符不是數字。打字機根本沒有CPU或內存,他們很好地處理這些“數字”,因為它只是文本。

證明 萬億 不是數字,而是文字: 它可以表示1萬億(十進制),4096(二進制)或281474976710656(十六進制)。它在不同的系統中具有更多的含義。的意思 萬億 是一個數字,存儲它是一個不同的故事(我們馬上就會回到它)。

存儲文本(在編程時調用它) 萬億 你需要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位CPU添加對32位字數的支持使其成為64位CPU(現在它本身可以在64位數字上運行,對吧?)。

我上面描述的所有內容都適用於具有8位字節和4字節字的二進制存儲器,它的工作方式幾乎相同:

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

但是,將這些數字轉換為十進制是很棘手的。 (但它 用十六進制很好地工作


190



你的答案讀起來相當居高臨下。 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


你也可以寫 “這句話是假的” 沒有你的計算機崩潰:) @斯科特的答案是某些計算框架的現實,但你的“寫”大量的問題暗示它只是純文本,至少在它被解釋之前。

編輯: 現在用 少諷刺 關於不同方式的更多有用信息a  可以存儲在內存中。我將用這些來描述這些 更高的抽象 即,現代程序員可能在將代碼翻譯成機器代碼以執行之前編寫代碼。

計算機上的數據必須限制在某個位置 類型並且這種類型的計算機定義描述了可以對該數據執行什麼操作以及如何(即比較數字,連接文本或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 作為分數的總和,它們的分母中只能有2的冪!將數字存儲為整數會不會更容易,但是同意將基數(十進制)點放在一起?這就是所謂的 固定點 數字,我們存儲的地方 1234100 但同意一個公約將其視為 1234.100 代替。

用於計算的相對更常見的類型是 floating point。它的工作方式非常簡潔,它使用一位來存儲符號值,然後使用一些來存儲指數和有效數。有些標准定義了這樣的分配,但是對於a 32位浮點數 你可以存儲的最大數量是壓倒性的

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

然而,這是以精確度為代價的。瀏覽器中可用的JavaScript使用64位浮點數,但它仍然無法正常運行。只需將其複製到地址欄中,然後按Enter鍵即可。擾流警報:結果是  將 0.3

javascript:alert(0.1+0.2);

還有更多替代類型,如Microsoft .NET 4.5 BigInteger,理論上沒有上限或下限,必須以“批次”計算;但也許那些更有吸引力的技術 了解 數學,就像Wolfram Mathematica引擎一樣,它可以精確地處理抽象值 無窮


40



你可以做到這一點 這個 現實。嘗試在星際迷航宇宙中這樣做。因為所有的火花和煙霧,只是退後一步。 - Michael Petrotta
這不是定點的工作原理。它實際上是一個系統,其中數字被縮放和偏置以產生小數點。在您的示例中,比例為1/1000,但也有定點數(特別是在計算機圖形中),如下所示:0 = 0.0,255 = 1.0 - 比例為1/255。 - Andon M. Coleman


關鍵是了解計算機如何 編碼 數字。

是的,如果計算機堅持使用單個字(32位系統上的4個字節)使用數字的簡單二進製表示來存儲數字,那麼32位計算機只能存儲最多2 ^ 32的數字。但是還有很多其他方法可以根據你想用它們實現的數字來編碼數字。

一個例子是計算機如何存儲浮點數。計算機可以使用一大堆不同的方法對它們進行編碼。標準 IEEE 754 定義編碼大於2 ^ 32的數字的規則。粗略地說,計算機可以通過將32位分成不同的部分來實現這一點,這些部分代表數字的一些數字和代表數字的其他位 尺寸 數字(即指數,10 ^ x)。這允許更大 範圍 大小方面的數字,但折衷精度(這可以用於許多目的)。當然,計算機也可以使用多於一個字來進行這種編碼,從而提高可用編碼數量的精確度。 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位數字系統,而電子計算機則使用2位數係統(二進制)。數字32和64恰好是2的冪。因此,百萬和萬億是10的冪。例如,我們使用這些數字比使用65536的數字更容易。

當我們將它們寫在紙上時,我們將大數字分成數字。計算機將數字分解為更多的數字。我們可以記下我們喜歡的任何數字,如果我們設計它們,也可以寫下計算機。


24





32位和64位指的是內存地址。您的計算機內存就像郵政信箱,每個都有不同的地址。 CPU(中央處理單元)使用這些地址來尋址RAM(隨機存取存儲器)上的存儲器位置。當CPU只能處理16位地址時,你只能使用32mb的RAM(當時看起來很大)。在32位時,它達到了4 + gb(當時看起來很大)。現在我們有64位地址,RAM進入太字節(這看起來很大)。
但是,程序能夠為存儲數字和文本等內容分配多個內存塊,這取決於程序並且與每個地址的大小無關。所以程序可以告訴CPU,我將使用10個地址塊存儲,然後存儲一個非常大的數字,或10個字母的字符串或其他。
附註:“指針”指向內存地址,因此32位和64位值表示用於訪問內存的指針大小。



15



除了細節之外的好答案 - 16位地址空間給你64kb,而不是32mb,像286這樣的機器有24位地址(16mb)。此外,對於64位地址,您遠遠超過太字節 - 更像是16艾字節 - 太字節是圍繞當前一代主板/ CPU的限制 - 而不是地址的大小。 - Phil
32位是指機器字大小,而不是內存地址。正如Phil所說,286是16位CPU,但是使用24位通過內存分段進行尋址。 x86 CPU是32位,但使用36位尋址。看到 PAE。 - gronostaj
@gronostaj井x86具有從386到Pentium的32位尋址。 - Ruslan
Upvote因為這是唯一正確的答案 - 32位是指32位內存尋址,而不是32位算術。 - user1207217
@ user1207217:??所以根據你的推理,例如Z80或8080是16位處理器(因為16位內存尋址和內存總線)? - pabouk


因為顯示數字是使用單個字符完成的,而不是整數。數字中的每個數字都用單獨的字符文字表示,其整數值由所使用的編碼定義 'a' 用ascii值表示 97,而 '1' 代表 49。檢查 ascii表在這裡
用於顯示'a'和'1'是相同的。它們是字符文字,而不是整數。允許每個字符文字在32位平台中具有最大值255,以8位或1字節大小存儲該值(這取決於平台,但是8位是最常見的字符大小),因此它們可以組合在一起並且可以是顯示。它們可以顯示多少單獨的字符取決於您擁有的RAM。如果你只有1個字節的RAM,那麼你只能顯示一個字符,如果你有1GB的RAM,你可以很好地顯示1024 * 1024 * 1024個字符(懶得做數學運算)。

然而,這個限制適用於計算,但我猜您對IPV4標準感興趣。雖然它與計算機並不完全相關 bit-size,它以某種方式影響了標準。創建IPV4標準時,它們將ip值存儲為32位整數。現在,一旦你給出了尺寸,它就成了標準。我們所知道的關於互聯網的一切都依賴於此,然後我們用盡了IP地址進行分配。因此,如果將IP標準修改為64位,那麼一切都將停止工作,包括您的路由器(我認為這是正確的)和其他網絡設備。因此必須創建一個新標準,它只是將32位整數與128位整數交換。並調整了標準的其餘部分。硬件製造商只需聲明他們支持這個新標準,它就會變成病毒。雖然不是那麼簡單,但我想你明白這一點。

免責聲明: 這裡提到的大多數觀點都符合我的假設。我可能在這裡錯過了重點,以使其更簡單。我對數字並不擅長,所以一定要錯過一些數字,但我的觀點是回答OP的答案,說明為什麼它不會崩潰PC。


13



我沒有投票,但你的答案有很多問題。 1 是ASCII中的0x31,而不是0x1。 1 GB = 1024 ^ 3 B.在引入32位CPU之前發明了IPv4,因此說地址以32位整數存儲與OP的問題相衝突。最後,IPv6使用的是128位地址,而不是64位地址。 - gronostaj


在處理器中,有“單詞”。 有不同的詞。當人們說“32位處理器”時,它們主要是指“內存總線寬度”。該字由不同的“字段”組成,它們指的是與發送(24位)和控制(其他位)相對應的計算機子系統。關於確切的數字我可能是錯的,通過手冊讓自己確定。

完全不同的方面是計算。 SSE和MMX指令集可以存儲長整數。在不損失生產力的情況下,最大長度取決於當前的SSE版本,但它總是大約64位的倍數。

目前的Opteron處理器可以處理256位寬的數字(我不確定整數,但浮動是肯定的)。

摘要:(1)總線寬度不直接連接到計算寬度,(2)即使不同的字(存儲器字,寄存器字,總線字等)也不相互連接,另外它們有8或16或24的公約數許多處理器甚至使用了6位字(但它的歷史)。


12



不是這樣,原版奔騰處理器有一個64位數據總線,用於高內存帶寬,即使它是一個32位處理器。 8088是一個帶有8位數據總線的16位處理器。 - doug65536