计算机如何将二进制数转换为其2的补码十进制等效形式

5

我的问题仅涉及二进制的补码。

假设我给你这个二进制数11111110,它以补码形式存储在一台机器上,我想让你找到它的十进制等效值。有些人可能会说它是-2,而有些人可能会说它是254,因为他们不知道它是有符号还是无符号的。(我知道它是一个有符号数,所以我取它的补码并加1,得到2,所以答案是-2。但如果我不知道符号,我会说是254)。

简而言之,计算机如何将存储在二进制补码中的这种表示转换为其十进制等效值而不出错?

计算机是否知道其符号?(如果是,则该信息存储在哪里?)

2个回答

11

从技术上讲,你不能将二进制表示的数字转换为十进制,因为计算机没有任何存储设施来表示十进制数。

实际上这听起来可能很荒谬,因为我们总是处理十进制表示的数字。但是这些十进制表示实际上从未以十进制形式存储。计算机所做的唯一事情就是在显示数字时将其转换为十进制表示。而且这种转换与程序构造和库设计有关。

我会举一个关于C语言的小例子。在C中,您有带符号和无符号整数变量。当您编写程序时,这些变量用于将数字存储到内存中。谁知道它们的符号?编译器知道。汇编语言有带符号和无符号操作。编译器跟踪所有变量的符号,并生成适当的有符号或无符号代码。因此,当程序被编译时,您的程序可以完美地使用带符号或无符号整数。

假设您使用了一个printf语句来打印一个整数变量,并且您使用了%d格式转换器来以十进制表示打印该值。这个转换将由C的标准输入输出库中定义的printf函数处理。该函数从内存中读取变量,使用简单的基本转换算法将二进制表示转换为十进制表示。但是算法的目标是一个字符序列,而不是整数。因此,该算法完成两件事情:它同时将二进制转换为十进制表示,将位转换为字符值(或更精确地说是ASCII代码)。printf应该知道数字的符号以便成功进行转换,并且这些信息是由编译器构造放置在编译时提供的。通过使用这些构造,printf可以检查整数是带符号还是无符号,并使用适当的转换方法。

其他编程语言也遵循类似的路径。实质上,数字总是以二进制形式存储的。有符号或无符号表示是由编译器/解释器知道的,因此是公共知识。十进制转换仅出于美观的原因进行,其目标是一个字符序列或字符串。


谢谢,这是高水平的,但如果我编写一个基本的引导加载程序,它打印一个负数(这个数字显然以2的补码形式存储在0x7c00之后的某个地方),如果我不告诉CPU它的符号,那么他(CPU)肯定会打印错误的结果?我还是不明白 :( - dimSutar
@dimSutar 当你从操作系统中移除电源时,类似的逻辑仍然成立。CPU有符号和无符号数字的指令,同样BIOS可以将带符号或无符号数字放到屏幕上。因此,您必须告诉CPU和BIOS所使用的正确形式。有人(您或其他任何人)将负数放入内存中。那个人还应该宣布存储数字时使用的符号约定。如果没有这个,你就没有任何办法知道,只能猜测。大多数情况下,使用的约定与常识相一致。例如,视频卡品牌代码从不带符号。 - infiniteRefactor

0

这是因为当您指定要使用有符号数字时,计算机将解释第一位[1]1111110作为由其余位1[1111110]组成的数字的符号。所以1表示负数,0表示正数; "char"可以存储从-127到127的数字; "unsigned char"可以存储从0到255的数字;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接