我的问题仅涉及二进制的补码。
假设我给你这个二进制数11111110,它以补码形式存储在一台机器上,我想让你找到它的十进制等效值。有些人可能会说它是-2,而有些人可能会说它是254,因为他们不知道它是有符号还是无符号的。(我知道它是一个有符号数,所以我取它的补码并加1,得到2,所以答案是-2。但如果我不知道符号,我会说是254)。
简而言之,计算机如何将存储在二进制补码中的这种表示转换为其十进制等效值而不出错?
计算机是否知道其符号?(如果是,则该信息存储在哪里?)
我的问题仅涉及二进制的补码。
假设我给你这个二进制数11111110,它以补码形式存储在一台机器上,我想让你找到它的十进制等效值。有些人可能会说它是-2,而有些人可能会说它是254,因为他们不知道它是有符号还是无符号的。(我知道它是一个有符号数,所以我取它的补码并加1,得到2,所以答案是-2。但如果我不知道符号,我会说是254)。
简而言之,计算机如何将存储在二进制补码中的这种表示转换为其十进制等效值而不出错?
计算机是否知道其符号?(如果是,则该信息存储在哪里?)
从技术上讲,你不能将二进制表示的数字转换为十进制,因为计算机没有任何存储设施来表示十进制数。
实际上这听起来可能很荒谬,因为我们总是处理十进制表示的数字。但是这些十进制表示实际上从未以十进制形式存储。计算机所做的唯一事情就是在显示数字时将其转换为十进制表示。而且这种转换与程序构造和库设计有关。
我会举一个关于C语言的小例子。在C中,您有带符号和无符号整数变量。当您编写程序时,这些变量用于将数字存储到内存中。谁知道它们的符号?编译器知道。汇编语言有带符号和无符号操作。编译器跟踪所有变量的符号,并生成适当的有符号或无符号代码。因此,当程序被编译时,您的程序可以完美地使用带符号或无符号整数。
假设您使用了一个printf
语句来打印一个整数变量,并且您使用了%d
格式转换器来以十进制表示打印该值。这个转换将由C的标准输入输出库中定义的printf
函数处理。该函数从内存中读取变量,使用简单的基本转换算法将二进制表示转换为十进制表示。但是算法的目标是一个字符序列,而不是整数。因此,该算法完成两件事情:它同时将二进制转换为十进制表示,将位转换为字符值(或更精确地说是ASCII代码)。printf
应该知道数字的符号以便成功进行转换,并且这些信息是由编译器构造放置在编译时提供的。通过使用这些构造,printf
可以检查整数是带符号还是无符号,并使用适当的转换方法。
其他编程语言也遵循类似的路径。实质上,数字总是以二进制形式存储的。有符号或无符号表示是由编译器/解释器知道的,因此是公共知识。十进制转换仅出于美观的原因进行,其目标是一个字符序列或字符串。
这是因为当您指定要使用有符号数字时,计算机将解释第一位[1]1111110
作为由其余位1[1111110]
组成的数字的符号。所以1表示负数,0表示正数;
"char"可以存储从-127到127的数字;
"unsigned char"可以存储从0到255的数字;