【问题标题】:How do computers translate everything to binary? When they see a binary code, how do they know if it represents a number or a word or an instruction?计算机如何将所有内容转换为二进制?当他们看到一个二进制代码时,他们怎么知道它是代表一个数字、一个字还是一条指令?
【发布时间】:2014-12-03 17:05:32
【问题描述】:

我知道计算机如何将数字转换为二进制。但我不明白的是,我听说计算机将所有内容(文字、指令……)翻译成二进制,而不仅仅是数字。这怎么可能?

你能给我一些例子吗?比如计算机如何将字母“A”翻译成二进制?

当计算机看到一个二进制代码时,它们怎么知道那长长的 0 和 1 字符串是代表一个数字还是一个单词或一条指令?

.

示例:

假设计算机程序员对字母“Z”进行了编码,以便将其转换为以下二进制字符串:11011001111011010111

所以当计算机遇到这个二进制字符串时,会将其翻译成字母“Z”。

但是当我们问这台计算机“709 乘以 1259 的乘积是什么?”时会发生什么?

计算机会回答我们“892631”。但是这个数字,当翻译成二进制时,是 11011001111011010111。

那么“Z”和“892631”有什么区别呢?

.

请注意,我对计算机科学知之甚少,所以请用简单的术语解释一下。

【问题讨论】:

标签: binary computer-science binaryfiles binary-data computer-architecture


【解决方案1】:

让我们在这里讨论一些基础知识:

  1. 假设您的硬盘驱动器只是一个圆形的铝板,并且到处都有小孔/斑点(只能使用显微镜才能看到)。 Spot是一个按字节分组的小洞——8位(1位就是1个洞)。
  2. RAM 类似于硬盘驱动器,但它是由硅制成的半导体,因此它可以以电场的形式存储信息,并且每个字节都有地址,因此速度更快。
  3. 计算机将您通过键盘输入的所有信息存储在硬盘驱动器中作为磁脉冲(表示为 1 以供人类理解)称为 1。如果没有信息,则该点(一个小孔)是空的,称为零。李>

让我们讨论你问题的第一部分 - 你能给我看一些例子吗?比如计算机如何将字母“A”翻译成二进制?

  1. 例如,您通过键盘输入字符“A”和“அ”。
  2. 字符“A”在 Unicode/ASCII 中表示为 65,在 base 2 二进制中是 01000001。操作系统将 A 映射到二进制。您输入的这个字符“A”现在作为 01000001 存储在硬盘中,并将出现在 8 个不同的位置(如最左边的数字 0 没有磁脉冲,第七位的 7 有磁脉冲等)。
  3. 在 RAM 的情况下,它以电脉冲的形式存储信息,因此当电源关闭时 RAM 会丢失所有信息。

现在,您在 RAM 或硬盘驱动器上看到的所有内容在给定字节中都是能量或没有能量,我们将其称为二进制格式以供人类理解(我们将其称为 0 表示没有能量,1 表示能量)。

现在取决于编译器,它必须如何存储。如果它是 AMD 处理器/Windows 操作系统上的 C 编译器,它会将值存储在 2 个字节中(5 个字节一个字节,6 个字节一个字节)。如果是 AMD 处理,存储值 5 的字节将位于 6 的右侧 - 它称为低端。 C 程序不支持字符“அ”,因为它需要超过 1 个字节来存储国际字符。

如果它是 Java 编译器,它使用称为 UTF-16 的 4 字节可变长度。对于字母“A”,它需要 1 个字节,因为 Unicode/ASCII 表示为 65。而如果您要存储国际语言字符,例如“அ”(类似于泰米尔语中的 A),则相应的 Unicode 值是 2949 和对应的二进制值为 11100000 10101110 10000101(3 个字节)。 Java 在存储和读取“A”和“அ”方面没有问题。

现在假设您使用 Java/Windows/AMD 处理器将字符“அ”作为类型字符 (Char) 存储在硬盘中。

现在假设您想使用 C 程序作为 Char 来阅读此内容。 C 编译器仅支持 ASCII,但不支持 Unicode 集的完整列表。在这里,C 将读取上述 3 个字节中最右边的(10000101)字节(对于 char 类型,它读取 1 个字节),你在屏幕上看到了什么?如果您要求程序打印,您的 C 程序将毫无问题地读取这 1 个字节并将其绘制在屏幕上。所以编译器是差异制造者。

****现在让我们讨论您问题的第二部分:** *而当计算机看到一个二进制代码时,它们怎么知道那一长串的0和1是代表一个数字还是一个字还是一条指令?***

现在,您将已编译的 Java 程序加载到 RAM 中的文本和数据区(RAM 在较高级别分为文本和数据区)。现在您要求处理器的 ALU 执行程序的一组指令,称为进程。

您编译的程序中的行是将数据从一个变量移动到另一个变量的指令。

当 ALU 执行第一条指令时,它会进入位于 RAM 外部的相应寄存器。处理器具有一组数据寄存器和一组指令寄存器。 ALU 现在知道什么寄存器是什么,基于它执行你的指令。

希望这会有所帮助。

【讨论】:

  • 这里有些过于简单化,但也有些错误。在您谈论使用 UTF-16 的 Java 的同一段中,您说 அ 表示为 11100000 10101110 10000101(3 个字节)。这显然不是真的,因为UTF-16 将 unicode 代码点编码为一个或多个 2 字节块。您显示的位模式类似于该代码点的 UTF-8 编码,基于第一个字节中的 3 个前导 1 位,指示 3 字节字符。
  • 另外,操作系统将 A 映射到二进制。 有点奇怪。计算机内部的一切都是二进制的。映射的输入是来自键盘的扫描码。 (或 USB 键盘驱动程序)。终端驱动程序或 GUI 事件传递程序会将按键映射到它们的 ASCII 或 UTF-8 或 UTF-16 代码,或任何字符集。或者对代码点进行 unicode,然后从那里编码成 UTF-8。
  • 谢谢,彼得。你的观点是对的。我很清楚给定的按键如何转换为 11 位扫描码(起始位、数据、奇偶校验位和停止位)并在 PS/2 或 USB 上作为位流发送,然后映射到相应的 ASCII 或UTF 基于我们在控制面板中选择的字符集。我不想对此进行深入研究,所以我通过将其声明为 OS 来过度简化它。
  • 彼得,再次感谢。我再次简化了在这种情况下国际字符需要 3 个字节的事实,因为相应的十进制值是 2949,十六进制是 0xb85。我的意思是它至少需要 3 个字节,但从技术上讲,如果它是使用 2 个字节集的 UTF-16,它需要 4 个字节。在这种情况下,它占用 4 个字节,最左边的一个将为 0。大多数人认为Java是UTF-8,但在字符或字符串的情况下不是休战,正如你所说的UTF-16。谢谢。以后我会让我的文章更加精确。
【解决方案2】:

计算机仅使用 7 位来存储字母/特殊字符,而它在存储数字时使用一个字节的全部 8 位。

让我们以“A”和“65”为例。

65/2 -- QUO 为 32,提醒为 1 1 2 的 0 次方为 1

32/2 quo 是 16,提醒是 0 01

16/2 quo 是 8,提醒是 0 001

8/2 quo 是 4,提醒是 0 0001

4/2 quo 是 2,提醒是 0 00001

2/2 quo 是 1,reminder 是 0 1000001 2 的 6 次方是 64

                             =========
                             1000001 binary repressents 65

字母 A 的 ASCII 值以二进制格式存储为 01000001(仅使用 7 位,第 8 位存储为 0 用于字母和特殊字符)。

我希望这会有所帮助。

【讨论】:

  • UTF-8 是一种广泛使用的字符编码,包括“特殊字符”和非拉丁字母表中的字母。它使用可变长度编码的所有 8 位(每个字符 1 到 4 个字节)。设置为 1 的前导位数 = 多字节字符中的总字节数。 en.wikipedia.org/wiki/UTF-8#Description
  • 您关于仅 7 位用于存储字母/特殊字符的说法是错误的。过时的 7 位 US-ASCII 代码是该声明适用的少数代码之一。您最喜欢的 Windows、Linux 或 MacOS 机器可能使用 Windows1252 之一,这是众多 ISO-8859 变体之一或 UTF-8,所有这些都使用全套 8 位代码。顺便提一句。周围还有 5 位代码,甚至还有像 en.wikipedia.org/wiki/DEC_Radix-50 这样的好奇心。
【解决方案3】:

So how would it make a difference between "Z" and "892631"?

它没有。对计算机来说,一切都是 0 和 1。在告诉处理器如何处理这些 0 和 1 之前,它们的原始位没有任何意义!

例如,我可以创建一个变量x 并将其值设为0b01000001(0b 表示“这是我用二进制描述的数字”)。然后我可以要求处理器为我将变量x 打印到屏幕上。但我首先必须告诉处理器x 是什么!

printf("%d", x); // this prints the decimal number 65

printf("%c", x); // this prints the character A

所以x 本身没有任何意义,除了原始位01000001。但作为程序员,我的工作是告诉计算机x 的真正含义。

【讨论】:

    【解决方案4】:

    计算机实际上并没有将任何东西转换成二进制,它从一开始就是二进制的,而计算机除了二进制之外什么都不知道。

    存储在内存中的字符A 将是01000001,并且计算机不会将其视为二进制数。当我们要求计算机将该数字显示为屏幕上的字符时,它会在字体定义中查找它的图形表示,以找到一些其他二进制数字发送到屏幕硬件。

    例如,如果计算机是 8 位 Atari,它会找到八个二进制值来表示屏幕上的字符 A

    00000000
    00011000
    00111100
    01100110
    01100110
    01111110
    01100110
    00000000
    

    如您所见,当图形硬件将二进制值绘制到屏幕上时,二进制值将转换为暗像素和亮像素。

    同样,无论我们对计算机中的数字做什么,都是移动二进制值、对二进制值进行计算并将它们转换为其他二进制值的所有方式。

    例如,如果您将A 的字符代码显示为十进制数,则计算机会计算出该数字的十进制表示为数字 6 (110) 和 5 (@987654327 @),将其转换为字符 6 (00110110) 和字符 5 (00110101),然后将它们转换为图形表示。

    【讨论】:

      【解决方案5】:

      这是一个很好的问题,而且需要数年时间和几个博士才能完全解释。我可以为您提供一个简单的答案,但要完全理解您将需要做更多的研究。我可以推荐一些麻省理工学院关于该主题的免费在线课程here

      在最低级别,字母 A 和数字 65 实际上使用相同的 0 和 1 序列存储。 1000001 如果我没记错的话。

      然后,计算机从内存中获取它时会决定它是什么。这意味着字母可以显示为数字,反之亦然。

      计算机知道它在寻找什么的方式是程序员告诉它它在寻找什么。程序员说我想在某某位置存储一个数字,然后计算机去寻找它。

      让我们提高一个级别,因为很少有程序在如此低的级别上编程了。其他程序(通常是编译器,它采用 C++ 之类的代码并将其转换为计算机可以理解的东西)确保我们正在访问的位置实际上是我们所说的。他们有额外的信息告诉他们这组 1 和 0 实际上是浮点类型(有小数点),而这组是整数(没有小数点)

      然后其他类型建立在这些类型之上,更大的整数、浮点数或字符串,编译器再次强制执行这些类型。

      这过于简单化了,我意识到这里的所有内容并不完全正确,但它会让你走上正确的道路。您可以查看其中一些主题以获得更好的想法:

      How instructions are differentiated from data?

      http://en.wikipedia.org/wiki/Computer_data_storage

      How is data, address and Instruction differentiated in Processor/Register/memory?

      http://en.wikipedia.org/wiki/Reference_(computer_science)

      希望这能让事情有所澄清。随时要求澄清!

      【讨论】:

      • 在这个答案的基础上,你得到了二进制,它是 0 和 1,并且在硬件上正常工作。进一步的抽象将其转换为汇编,其中包含简单的指令,如 ADD、SUB、DIV、MUL 等,并解释二进制文件应如何交互。这仍然很容易出错,最终您拥有了带有语法和句法的简单编程语言,然后将它们编译为汇编和二进制,将人类的话翻译成机器语言。
      猜你喜欢
      • 2016-01-08
      • 1970-01-01
      • 2017-01-16
      • 2020-03-05
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 1970-01-01
      • 2015-08-01
      相关资源
      最近更新 更多