如果 32 位机器最多只能处理 2^32 的数字,为什么我可以在不崩溃的情况下写入 1000000000000(万亿)?

Ben*_*mk2 376 memory cpu 64-bit 32-bit computer-architecture

32 位计算机只能存储最多 2 31 - 1 的有符号整数。
这就是为什么我们已经用完 IPv4 地址并进入了 64 位时代。

但是,数字 2 31 - 1 (2,147,483,647) 不如数字 1 万亿 (1,000,000,000,000) 大,我似乎可以在不崩溃的情况下正常显示。

有人可以解释为什么会这样吗?

Sco*_*ain 791

我通过问你一个不同的问题来回答你的问题:

你怎么用手指数到 6?

您可能会用一只手数到最大的数字,然后当您用完手指时,您会继续使用第二只手。计算机做同样的事情,如果他们需要表示一个大于单个寄存器可以容纳的值,他们将使用多个 32 位块来处理数据。

  • 有趣,@codename。那么你如何用手指数到 32 或更多(即一旦 2^5 用完)?;) 移动到另一只手的类比很好......即使二进制延迟了移动到另一只手的需要。_我想看到的_是用足部灵巧计数到 1,024 或更多,以移动到脚趾以二进制进一步计数 - 高达 1,048,575!:) 这可能是 20 位的子板功率。:P (16认同)
  • **请保持评论主题并与讨论此答案的技术方面相关。** 已从此答案中删除了 60 多条笑话评论,我们希望避免锁定帖子。 (14认同)
  • 我认为这不是相关问题的答案。@Bigbio2002 的回答是正确的。这里的“1000000000000”不是数字而是文本,就像“adsfjhekgnoregrebgoregnkevnregj”一样。你说的是真的,但我强烈觉得这不是正确的答案。看到这么多赞... (2认同)

Big*_*002 396

您是正确的,32 位整数不能包含大于 2^32-1 的值。但是,这个 32 位整数的值和它在屏幕上的显示方式是完全不同的两件事。打印的字符串“1000000000000”在内存中不是由 32 位整数表示的。

字面上显示数字“1000000000000”需要 13 个字节的内存。每个单独的字节最多可以容纳 255 个值。它们都不能容纳整个数值,而是单独解释为 ASCII 字符(例如,字符 ' 0' 表示为十进制值 48,二进制值00110000),它们可以串成一种对您(人类)有意义的格式。


编程中的一个相关概念是类型转换,即计算机将如何解释特定的0s 和1s流。在上面的例子中,它可以被解释为一个数值、一个字符,甚至完全是其他的东西。虽然 32 位整数可能无法容纳 1000000000000 的值,但 32 位浮点数将能够使用完全不同的解释。

至于计算机如何在内部处理和处理大数,有 64 位整数(最多可以容纳 160 亿的值)、浮点值以及可以处理任意大数的专用库数字。

  • 实际上,这大部分是正确的,但并不完全正确。一个 32 点的浮点数不太可能准确地表示 1000000000000。它将表示一个非常接近所需数字但不完全是的数字。 (22认同)
  • 没错,可以。然而,这并不是人们所说的“float”格式,它通常指的是当前计算机中标准浮点处理器存储和使用的 32 位浮点数。 (15认同)
  • @TimB:您听说过decimal32 格式吗?它是 IEEE 754-2008 标准的一部分。这种格式能够正确表示这个数字:) (6认同)
  • @TimB:但是 64 位浮点数可以轻松准确地表示“1000000000000”。它是 10^12,或 2^12 * 5^12;5^12 需要 28 位尾数。 (4认同)
  • @TimB 确实如此。最接近可以表示为 float32 的数字是 999999995904 (2认同)

gro*_*taj 190

首先,32 位计算机可以在单个机器字中存储多达 2 32 -1 的数字。机器字是 CPU 可以以自然方式处理的数据量(即,对这种大小数据的操作是在硬件中实现的,通常执行速度最快)。32 位 CPU 使用由 32 位组成的字,因此它们可以在一个字中存储从 0 到 2 32 -1 的数字。

其次,1万亿10000亿是两个不同的东西。

  • 1万亿是一个数字的抽象概念
  • 1000000000000 是文本

通过按1一次然后按012 次,您可以输入文本。1输入10输入0。看?您正在输入字符。字符不是数字。打字机根本没有 CPU 或内存,它们可以很好地处理这样的“数字”,因为它只是文本。

证明1000000000000不是数字,而是文本:它可以表示 1 万亿(十进制)、4096(二进制)或 281474976710656(十六进制)。它在不同的系统中具有更多的含义。1000000000000 的含义是一个数字,而存储该数字是另一回事(我们稍后再讨论)。

要存储文本(在编程中它被称为字符串1000000000000你需要 14 个字节(每个字符一个加上一个终止的 NULL 字节,基本上意味着“字符串在这里结束”)。那是4个机器字。3个半就够了,但正如我所说,对机器词的操作是最快的。让我们假设ASCII用于文本编码,所以在内存中看起来就像这样:(对应转换为ASCII码01二进制,在一个单独的行每个单词)

00110001 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00110000 00110000 00110000
00110000 00000000 00000000 00000000
Run Code Online (Sandbox Code Playgroud)

一个词可以容纳四个字符,其余的移到下一个。其余部分移至下一个字,直到所有内容(包括第一个 NULL 字节)都适合为止。

现在,回到存储数字。它就像处理溢出的文本一样,但它们是从右到左安装的。这听起来可能很复杂,所以这里有一个例子。为简单起见,我们假设:

  • 我们想象中的计算机使用十进制而不是二进制
  • 一个字节可以容纳数字 0..9
  • 一个字由两个字节组成

这是一个空的 2 字内存:

0 0
0 0
Run Code Online (Sandbox Code Playgroud)

让我们存储数字 4:

0 4
0 0
Run Code Online (Sandbox Code Playgroud)

现在让我们添加 9:

1 3
0 0
Run Code Online (Sandbox Code Playgroud)

请注意,两个操作数都适合一个字节,但不是结果。但是我们还有另一个可以使用。现在让我们存储 99:

9 9
0 0
Run Code Online (Sandbox Code Playgroud)

同样,我们使用第二个字节来存储数字。让我们加1:

0 0
0 0
Run Code Online (Sandbox Code Playgroud)

哎呀...这就是所谓的整数溢出,是许多严重问题的原因,有时非常昂贵

但是如果我们预计会发生溢出,我们可以这样做:

0 0
9 9
Run Code Online (Sandbox Code Playgroud)

现在加1:

0 1
0 0
Run Code Online (Sandbox Code Playgroud)

如果您删除字节分隔空格和换行符,它会变得更清楚:

0099    | +1
0100
Run Code Online (Sandbox Code Playgroud)

我们已经预测可能会发生溢出,我们可能需要额外的内存。以这种方式处理数字不如处理单个单词的数字快,它必须在软件中实现。将两个 32 位字数的支持添加到 32 位 CPU 有效地使其成为 64 位 CPU(现在它可以在本机上操作 64 位数字,对吗?)。

我上面描述的所有内容也适用于具有 8 位字节和 4 字节字的二进制内存,它的工作方式几乎相同:

00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111    | +1
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000
Run Code Online (Sandbox Code Playgroud)

但是,将这些数字转换为十进制系统很棘手。(但它适用于十六进制

  • @MirroredFate 我不同意“显然是在谈论这个数字”。OP 说“显示良好”,这显然是在对我说“10000000000000”这个文字...... (26认同)
  • 你的回答相当傲慢。OP 显然在谈论数字,而不是文字:“大如数字 1 万亿(1000000000000)”。此外,您几乎在谈论 [任意精度算术](http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic),但您从未真正提及您所说的任何术语...... (21认同)
  • “1万亿”也是一个字符串 (12认同)
  • @yannbane 'A' 是一个字符而不是一个数字。'?是一个字符而不是一个数字。'1' 是一个字符,而不是一个数字。字符只是符号。它们可以表示数字或数字,但绝对不是数字。“1”可以代表一、十、百、千等,它只是一个符号,代表一个数字,可以是数字或其一部分。“10”(字符串)可以表示两个、八个、十个或十六个等等。但是当你说你有十个苹果时,你使用的是十个数字,每个人都知道你的意思。字符和数字之间存在巨大差异。 (4认同)
  • @ElzoValugi 是。我必须找到某种方式来呈现抽象数字的概念,而不是代表数字的字符串。我相信“1 万亿”是一种更好且不那么模糊的方法(请参阅答案中的证明)。 (3认同)
  • @yannbane 或者,如果这不能说服您,那么让我们尝试严格的“计算机化”方法。查看 [ASCII 表](http://www.asciitable.com):如果数字 1 与字符 '1' 相同,那么对于您的计算机,显然 1 等于 49。这个结论很荒谬,但推理是正确的,所以假设肯定是错误的:1 和 '1' 不是一回事。 (3认同)
  • “1万亿”并不一定像你想象的那么明确...... http://en.wikipedia.org/wiki/Long_and_short_scales#Comparison (2认同)

Ole*_*leg 40

您还可以编写“此声明为假”而不会导致计算机崩溃:) @Scott 的答案对于某些计算框架来说是正确的,但是您“编写”大量数字的问题意味着它只是纯文本,至少直到它被解释。

编辑:现在用更少的讽刺来提供有关数字在内存中存储的不同方式的更多有用信息。我将用更高的抽象来描述这些,即现代程序员可能在将代码转换为机器代码以供执行之前编写代码。

计算机上的数据必须限制为某种类型,这种类型的计算机定义描述了可以对这些数据执行哪些操作以及如何执行(即比较数字、连接文本或对布尔值进行 XOR)。您不能简单地向数字添加文本,就像您不能将数字乘以文本一样,因此其中一些值可以在类型之间进行转换。

让我们从无符号整数开始。在这些值类型中,所有位都用于存储有关数字的信息;yours 是一个32 位无符号整数的示例,其中可以存储来自0to 的任何值2^32-1。是的,根据所使用平台的语言或体系结构,您可以使用 16 位整数或 256 位整数。

如果你想得到负数怎么办?直观地说,有符号整数就是游戏的名称。公约是从分配的所有值-2^(n-1)2^(n-1)-1-这样,我们避免处理两种方式来写的混乱+0-0。因此,一个 32 位有符号整数将保存从-2147483648to的值2147483647。整洁,不是吗?

好的,我们已经介绍了整数,这些整数是没有小数部分的数字。表达这些比较棘手:非整数部分显然只能介于0和之间1,因此用于描述它的每一个额外位都会增加其精度:1/2、1/4、1/8...问题是,你不能将一个简单的小数精确地表示0.1为分母中只能有 2 次幂的分数之和!将数字存储为整数是不是更容易,但同意将基数(小数)点代替?这称为定点数,我们在其中存储1234100但同意将其读取为的约定1234.100

用于计算的相对更常见的类型是floating point. 它的工作方式非常简洁,它使用一位来存储符号值,然后使用一些来存储指数和有效数。有定义此类分配的标准,但对于32 位浮点数,您能够存储的最大数字是压倒性的

(2 - 2^-23) * 2^(2^7 - 1) ? 3.4 * 10^38
Run Code Online (Sandbox Code Playgroud)

然而,这是以精度为代价的。浏览器中可用的 JavaScript 使用 64 位浮点数,但它仍然无法正确处理。只需将其复制到地址栏中,然后按 Enter。剧透警告:结果不会0.3

javascript:alert(0.1+0.2);
Run Code Online (Sandbox Code Playgroud)

还有更多替代类型,例如Microsoft .NET 4.5 的BigInteger,理论上没有上限或下限,必须“分批”计算;但也许更吸引人的技术是那些理解数学的技术,比如 Wolfram Mathematica 引擎,它可以精确地处理像infinity这样的抽象值。

  • 你可以在*这个*现实中做到这一点。尝试在星际迷航宇宙中这样做。由于所有的火花和烟雾,请先退后一步。 (9认同)

mat*_*ack 31

关键是了解计算机如何编码数字。

没错,如果计算机坚持使用单个字(32 位系统上为 4 个字节)的数字的简单二进制表示来存储数字,那么 32 位计算机最多只能存储 2^32 的数字。但是还有很多其他方法可以对数字进行编码,具体取决于您想用它们实现什么目的。

一个例子是计算机如何存储浮点数。计算机可以使用大量不同的方式对它们进行编码。标准IEEE 754定义了对大于 2^32 的数字进行编码的规则。粗略地说,计算机可以通过将 32 位分成代表数字的某些数字的不同部分和代表数字大小的其他位(即指数,10^x)来实现这一点。这允许更大的范围数字的大小,但会影响精度(这对于许多用途来说都可以)。当然,计算机也可以使用多个字进行这种编码,以提高可用编码数字大小的精度。IEEE 标准的简单十进制 32 版本允许数字具有大约 7 位十进制数字的精度和数量级高达大约 10^96 的数字。

但是,如果您需要额外的精度,还有许多其他选择。显然,您可以在编码中无限制地使用更多单词(尽管转换为编码格式和转出编码格式会造成性能损失)。如果您想探索一种可以实现的方法,有一个很棒的 Excel 开源插件,它使用一种编码方案,允许数百位的计算精度。该加载项称为 Xnumbers,可在此处获得。代码在 Visual Basic 中,这不是最快的,但具有易于理解和修改的优点。这是了解计算机如何实现更长数字编码的好方法。您可以在 Excel 中处理结果,而无需安装任何编程工具。


use*_*322 24

这一切都在你的问题中。

您可以在纸上写下您喜欢的任何数字。尝试在一张白纸上写上一万亿个点。它缓慢且无效。这就是为什么我们有一个 10 位系统来表示这些大数字。我们甚至有像“百万”、“万亿”等大数字的名字,所以你不要one one one one one one one one one one one...大声说出来。

32 位处理器旨在最快速、最有效地处理长度正好为 32 位二进制数字的内存块。但我们,人们,通常使用 10 位数字系统,而计算机,作为电子,使用 2 位系统(二进制)。数字 32 和 64 恰好是 2 的幂。百万和一万亿是 10 的幂。例如,我们使用这些数字比使用多个 65536 更容易。

当我们把大数字写在纸上时,我们将大数字分解成数字。计算机将数字分解成更多的数字。我们可以写下我们喜欢的任何数字,如果我们这样设计,计算机也可以。


小智 15

32bit 和 64bit 是指内存地址。您的计算机内存就像邮局信箱,每个信箱都有不同的地址。CPU(中央处理单元)使用这些地址来寻址 RAM(随机存取存储器)上的内存位置。当 CPU 只能处理 16 位地址时,您只能使用 32mb 的 RAM(当时看起来很大)。使用 32 位时,它达到了 4+gb(当时看起来很大)。现在我们有了 64 位地址,RAM 达到了 TB(看起来很大)。
然而,程序能够为诸如存储数字和文本之类的事情分配多个内存块,这取决于程序,与每个地址的大小无关。因此,程序可以告诉 CPU,我将使用 10 个地址存储块,然后存储一个非常大的数字,或者 10 个字母的字符串或其他任何内容。
旁注:内存地址由“指针”指向,因此 32 位和 64 位值表示用于访问内存的指针的大小。

  • 32 位是指机器字大小,而不是内存地址。正如 Phil 所提到的,286 是 16 位 CPU,但使用 24 位通过内存分段进行寻址。x86 CPU 是 32 位的,但使用 36 位寻址。请参阅 [PAE](https://en.wikipedia.org/wiki/Physical_Address_Extension)。 (4认同)
  • 除了细节之外,很好的答案 - 16 位地址空间为您提供 64kb,而不是 32mb,而像 286 这样的机器有 24 位地址(16mb)。此外,使用 64 位地址,您将远远超出 TB - 更像是 16 EB - TB 大约是当代主板/CPU 所施加的限制 - 而不是地址的大小。 (2认同)

noo*_*oob 13

因为显示数字是使用单个字符完成的,而不是整数。数字中的每个数字都用一个单独的字符文字表示,其整数值由所使用的编码定义,例如'a'用 ascii value表示97,而'1'49. 在此处检查ascii 表
显示 'a' 和 '1' 是相同的。它们是字符文字,而不是整数。在 32 位平台中,每个字符文字的最大值为 255,以 8 位或 1 字节大小存储该值(这取决于平台,但 8 位是最常见的字符大小),因此它们可以组合在一起并且可以显示。它们可以显示多少单独的字符取决于您拥有的 RAM。如果你只有 1 字节的内存,那么你只能显示一个字符,如果你有 1GB 的内存,你可以很好地显示 1024*1024*1024 个字符(懒得计算了)。

但是,此限制适用于计算,但是我猜您对 IPV4 标准感兴趣。虽然它并不完全与计算机有关bit-size,它以某种方式影响了标准。创建 IPV4 标准时,他们将 ip 值存储为 32 位整数。现在一旦你给出了尺寸,它就成为了标准。我们所知道的关于互联网的一切都依赖于此,然后我们用完了要分配的 IP 地址。因此,如果 IP 标准被修改为 64 位,一切都将停止工作,包括您的路由器(我认为这是正确的)和其他网络设备。因此必须创建一个新标准,它只是将 32 位整数与 128 位整数交换。并调整了其余的标准。硬件制造商只需要声明他们支持这个新标准,它就会像病毒一样传播开来。虽然这不是那么简单,但我想你明白了。

免责声明:这里提到的大部分观点都符合我的假设。我可能错过了这里的重要点,以使其更简单。我不擅长数字,所以一定错过了一些数字,但我的意思是回复 OP 关于为什么它不会使 PC 崩溃的答案。

  • 我没有投反对票,但你的回答有很多问题。`1` 在 ASCII 中是 0x31,而不是 0x1。1 GB = 1024^3 B. IPv4 wad 在引入 32 位 CPU 之前发明,因此说地址以 32 位整数存储与 OP 的问题相冲突。最后,IPv6 使用 128 位地址,而不是 64 位地址。 (2认同)

小智 13

在处理器中,有“词”。有不同的说法。当人们说“32 位处理器”时,他们的意思主要是“内存总线宽度”。这个词由不同的“域”组成,指的是计算机对应于传输(24位)和控制(其他位)的子系统。我可能对确切数字有误,请通过手册确定。

完全不同的方面是计算。SSE 和 MMX 指令集可以存储长整数。不损失生产力的最大长度取决于当前的 SSE 版本,但它总是大约 64 位的倍数。

当前的 Opteron 处理器可以处理 256 位宽的数字(我不确定整数,但可以肯定的是浮点数)。

总结:(1)总线宽度不直接与计算宽度相关,(2)即使不同的字(内存字,寄存器字,总线字等)也不相互连接,否则它们的公约数约为8或16或24. 许多处理器甚至使用 6 位字(但它的历史)。


Ada*_*vis 10

计算设备的目的通常是接受、处理、存储和发出数据。底层硬件只是帮助执行这四种功能的机器。没有软件,它什么也做不了。

软件是告诉机器如何接受数据、如何处理数据、如何存储数据以及如何将数据提供给他人的代码。

底层硬件总是有局限性。在 32 位机器的情况下,大多数处理数据的寄存器只有 32 位宽。但这并不意味着机器不能处理超过 2^32 的数字,这意味着如果你想处理更大的数字,机器可能需要一个以上的周期来接受它,处理它,存储它它,或发出它。

该软件告诉机器如何处理数字。如果软件设计用于处理大数,它会向 CPU 发送一系列指令,告诉它如何处理大数。例如,您的数字可以由两个 32 位寄存器表示。如果您想将 1,234 添加到您的数字中,软件会告诉 CPU 首先将 1,234 添加到低位寄存器,然后检查溢出位以查看该加法是否导致数字对于低位寄存器来说太大。如果是,则将高位寄存器加 1。

以同样的方式教小学生进行加法运算,CPU 可以被告知处理比单个寄存器所能容纳的更大的数字。对于大多数通用数学运算,对于任何实际大小的数字,都是如此。


小智 10

不同之处在于我们如何在计算机中存储数据。

您是对的,对于理论上的 8 位机器,我们只能在单个处理器寄存器或内存地址中存储 2^8 个值。(请记住,根据所使用的处理器、内存架构等,从“机器”到“机器”会有所不同。但现在,让我们坚持使用假设的“刻板印象”机器。)

对于理论上的 16 位机器,寄存器/内存位置中的最大值为 2^16,对于 32 位机器,为 2^32 等。

多年来,程序员设计了各种诡计来存储和处理大于单个处理器寄存器或内存地址所能存储的数字。存在许多方法,但它们都涉及使用多个寄存器/内存地址来存储大于其“本机”寄存器/内存位置宽度的值。

所有这些方法都是有益的,因为机器可以存储/处理大于其本机容量的值。缺点是几乎所有方法都需要多个机器指令/读取/等。处理这些数字。对于偶尔的大数字,这不是问题。当处理大量的大量(大内存地址具体地)涉及的开销会减慢速度。

因此,普遍希望使寄存器、内存位置和内存地址硬件“越来越宽”,以便“本地”处理大量数字,从而可以用最少的操作次数来处理这些数字。

由于数字大小是无限的,处理器寄存器/内存大小/寻址始终是本机数字大小和实现越来越大的宽度所涉及的成本的平衡。


Guf*_*ffa 8

32 位计算机在单个机器字中最多只能存储 2^32 的数字,但这并不意味着它们不能处理更大的数据实体。

32位计算机的含义一般是数据总线和地址总线都是32位宽,也就是说计算机可以同时处理4GB的内存地址空间,通过数据总线一次发送4个字节的数据.

然而,这并不限制计算机处理更多数据,它只需要在通过数据总线发送数据时将数据分成四个字节块。

常规的英特尔 32 位处理器可以在内部处理 128 位数字,这样您就可以毫无问题地处理 10000000000000000000000000000000000000 之类的数字。

您可以处理比计算机中大得多的数字,但是计算必须由软件完成,CPU 没有处理大于 128 位数字的指令。(它可以以浮点数的形式处理更大的数字,但是你只有 15 位的精度。)


maf*_*afu 6

只是在许多其他答案中添加注释,因为这是这个问题中一个非常重要的事实,但被遗漏了。

“32 位”指的是内存地址宽度。它与寄存器大小无关。许多 32 位 CPU 可能有 64 位甚至 128 位寄存器。特别是关于 x86 产品线,最近的消费类 CPU 都是 64 位,拥有多达 256 位的特殊用途寄存器。

寄存器宽度和地址宽度之间的这种差异自古就存在,当时我们有 4 位寄存器和 8 位地址,反之亦然。

很容易看出,无论寄存器大小如何,存储大量数字都没有问题,如其他答案中所述。

寄存器,无论它们的大小如何,也可以用更大的数字进行额外计算的原因是,太大的计算可以分解成几个适合寄存器的较小的计算(只是稍微复杂一点事实上)。


Kyl*_*and 6

已经给出的答案实际上非常好,但它们往往从不同的方面解决问题,因此呈现出不完整的图景。在我看来,它们也有点过于技术化。

因此,只是为了澄清一些其他答案中暗示但未明确表达的内容,我认为这是问题的关键:

您在问题中混淆了几个概念,其中一个(“32 位”)实际上可以指代各种不同的事物(不同的答案有不同的解释)。这些概念都与在各种计算上下文中使用(或可用)的位数(1 和 0)有关(我的意思是希望通过下面的示例得到澄清),但这些概念在其他方面是无关的

明确:

  • “IPv4/6”是指互联网协议,一组定义信息如何在互联网上打包和解释的规则。IPv4 和 IPv6 之间的主要(或至少是最广为人知的)区别在于 IPv6 中的地址空间(即可用于区分网络上不同位置的地址集)更大。这与通过网络发送的每个数据包中有多少位被分配(即预留用于)识别数据包的发送者和预期接收者有关。
    • 非计算类比:每个数据包就像一封通过蜗牛邮件发送的信件,地址空间就像在信封上写下地址和返回地址时“允许”使用的字符数量。
    • 到目前为止,我没有在任何其他答案中看到这一点。
  • 计算机内存“字”(32 位和 64 位)通常可以被认为是计算机使用或“思考”的最小数据块。这些数据位组合在一起构成其他数据位,例如文本块或更大的整数。
  • 32 位指针可能是也可能不是字,但它们仍然被原子地处理(即作为不能分解为更小的组件的单个单元)。指针是计算机可以记录任意数据块在内存中位置的最低级别方式。请注意,计算机(或者实际上是操作系统)使用的指针大小限制了单个指针可以访问的内存范围,因为指针可以“指向”的内存位置只有尽可能多因为指针本身有可能的值。这类似于 IPv4 限制可能的互联网地址范围的方式,但确实限制了可以存在于例如特定网页中的数据量。但是,指针大小确实限制指针可以指向的数据本身的大小。(有关允许数据大小超出指针范围的方案示例,请查看 Linux 的inode 指针结构。请注意,“指针”一词的用法与典型用法略有不同,因为指针通常指的是指向随机存取存储器,而不是硬盘空间。)
    • 非计算类比:嗯……这个有点棘手。也许用于索引图书馆资料的杜威十进制系统有点类似?或者任何索引系统,真的。
    • 请参阅SiteNook 的回答
    • 请注意,我对上述指针的解释省略了一些微妙的细节,可以说并不完全正确。然而,在程序员直接使用指针工作的编程语言中,我绘制的思维模式通常足以满足实际目的。
  • 数字,一个计算机是“能够显示”不(出于实用的目的)通过计算机的硬件或操作系统的限制; 它们被视为任何其他文本。

请注意,这并不是对短语“32 位”的完整解释列表。

额外的功劳:要真正了解数字和原始计算机内存块之间的基本哲学区别,请阅读有关图灵机的一些内容。


Dee*_*Dee 5

例如,如果您在计算器中写 1000000000000,计算机会将其计算为带小数点Real 类型数字。您提到的 32 位限制涉及更多所有没有小数点的整数类型数字。不同的数据类型使用不同的方法如何进入位/字节。

整数类型数字:此表可以帮助您抓住要点 ( http://msdn.microsoft.com/en-us/library/296az74e.aspx )。这触及了 C++ 的限制。例如Int64 类型编号的限制从 -9223372036854775808 到 9223372036854775807。

实型数字:实型数字包含带浮点数指数的值,您可以输入更大的数字,但准确度/精度有限。(http://msdn.microsoft.com/en-us/library/6bs3y5ya.aspx)例如,C++ 中的 LDBL(大双精度数)的最大指数为 308,因此您可能可以输入或具有结果数9.999 x 10^308,这意味着您将理论上有 308(+1) 个数字,9但只有 15 个最重要的数字将用于表示它,其余的将丢失,因为精度有限。

此外,有不同的编程语言,它们可能有不同的数量限制实现。因此,您可以想象专门的应用程序可以处理比 C++ 大得多(和/或更精确)的数字。


小智 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);
Run Code Online (Sandbox Code Playgroud)

所以基本上它与使用普通的 + - * / 运算符相同,只是使用一个库来分解数字并将它们内部存储为多个机器字大小(即 32 位)的数字。还有 scanf() 类型函数用于处理将文本输入转换为整数类型。

的结构mpz_t与 Scott Chamberlain 用两只手数到 6 的例子完全一样。它基本上是一个机器字大小mp_limb_t类型的数组,当一个数字太大而无法放入一个机器字时,GMP 使用 multiplemp_limb_t来存储数字的高/低部分。


小智 5

在您的脑海中,您只知道 10 个不同的数字。0 到 9。在您的大脑内部,这肯定与计算机中的编码不同。

计算机使用位来编码数字,但这并不重要。这只是工程师选择编码内容的方式,但您应该忽略它。你可以把它想象成一台 32 位计算机有超过 40 亿个不同值的唯一表示,而我们人类有 10 个不同值的唯一表示。

每当我们必须理解更大的数字时,我们就会使用一个系统。最左边的数字是最重要的。它比下一个重要 10 倍。

一台能够区分 40 亿个不同值的计算机,同样必须使一组值中最左边的值比该组中的下一个值重要 40 亿倍。实际上,计算机根本不在乎。它不会为数字分配“重要性”。程序员必须编写特殊的代码来解决这个问题。

每当一个值大于唯一符号的数量时,在人类心中是 9,你就在左边的数字上加 1。

3+3=6
Run Code Online (Sandbox Code Playgroud)

在这种情况下,该数字仍然适合单个“插槽”

5+5=10. This situation is called an overflow.
Run Code Online (Sandbox Code Playgroud)

所以人类总是处理没有足够的独特符号的问题。除非计算机有一个系统来处理这个问题,否则它只会写 0,忘记还有一个额外的数字。幸运的是,在这种情况下,计算机有一个“溢出标志”。

987+321 is more difficult.
Run Code Online (Sandbox Code Playgroud)

你可能在学校学到了一种方法。一种算法。算法非常简单。首先添加两个最左边的符号。

7+1=8, we now have ...8 as the result so far
Run Code Online (Sandbox Code Playgroud)

然后您移动到下一个插槽并执行相同的添加。

8+2=10, the overflow flag is raised. We now have ...08, plus overflow.
Run Code Online (Sandbox Code Playgroud)

由于我们有溢出,这意味着我们必须在下一个数字上加 1。

9+3=12, and then we add one due to overflow. ...308, and we had another overflow.
Run Code Online (Sandbox Code Playgroud)

没有更多的数字要添加,所以我们简单地创建一个插槽和插入器 1,因为溢出标志被引发。

1308
Run Code Online (Sandbox Code Playgroud)

A computer does it exactly the same way, except it has 2^32 or even better 2^64 different symbols, instead of only 10 like humans.

On a hardware level, the computer works on single bits using exactly the same method. Luckily, that is abstracted away for programmers. Bits is only two digits, because that is easy to represent in a power line. Either the light is on, or it is off.

Finally, a computer could display any number as a simple sequence of characters. That's what computers are best at. The algorithm for converting between a sequence of characters, and an internal representation is quite complex.