Math 两个';s补码——负数是如何处理的?

Math 两个';s补码——负数是如何处理的?,math,twos-complement,Math,Twos Complement,我的理解是,数字是用两个人的赞美来否定的,我的理解是:!num+1。 所以我的问题是,这是否意味着,对于变量'foo'=1,一个被否定的'foo'将与变量'bar'=255完全相同。 如果我们要检查-'foo'='bar'或-'foo'==255,我们会得到它们相等吗? 我知道有些语言,比如Java,保留了一个符号位——因此比较会产生错误。哪些语言没有呢?我假设汇编程序/本机没有符号位 除此之外,我还了解到当一个“负数”添加到另一个(任何符号)数字时设置的零标志或结转标志。由于2的补码的工作方式

我的理解是,数字是用两个人的赞美来否定的,我的理解是:!num+1。 所以我的问题是,这是否意味着,对于变量'foo'=1,一个被否定的'foo'将与变量'bar'=255完全相同。 如果我们要检查-'foo'='bar'或-'foo'==255,我们会得到它们相等吗? 我知道有些语言,比如Java,保留了一个符号位——因此比较会产生错误。哪些语言没有呢?我假设汇编程序/本机没有符号位

除此之外,我还了解到当一个“负数”添加到另一个(任何符号)数字时设置的零标志或结转标志。由于2的补码的工作方式,每当添加该标志时都会设置该标志,0x01+0xff=0x00(前导1被截断)。这面旗子到底是用来干什么的

我的最后一个问题是,对于其他数学运算(比如乘法),我是否需要重新求反这个数(所以现在是正数),执行运算,然后求反结果?例如!((!负+1)*正+1

编辑
完成了问题,请随意提问。

是的,在2的补码中,数字x表示为~x+1,其中~x是x的二进制数字在某些固定数字位中的位补码。例如,对于8位,x的二进制数字为00000000 1,因此按位补码为1111111 0,加1产生11111111

无法区分8位2的补码中的-1和8位二进制(无符号)中的255。它们都有相同的位表示:11111111。如果您同时使用这两个数字,您必须分别记住哪一个是8位2的补码,哪一个是纯8位二进制,或者必须使用8位以上的数字。换句话说,在原始位级别,11111111仅为8位;在我们决定如何解释它之前,它没有任何价值

Java和典型的其他语言不维护与数字值分开的符号位;符号是数字编码的一部分。此外,典型语言不允许您比较不同的类型。如果有一个2的补码x和一个无符号y,则在比较之前必须将其中一个转换为另一个的类型,或者必须将它们都转换为第三个类型。因此,如果您比较x和y,并且一个转换为另一个,那么转换将溢出或换行,并且您无法期望得到正确的数学结果。要比较这两个数字,我们可以将它们转换为更宽的整数,例如32位,然后进行比较。将8位2的补码11111111转换为32位整数会产生-1,将8位普通二进制11111111转换为32位整数会产生255,然后比较报告它们不相等

您阅读的零标志和进位标志是在计算机处理器中执行比较指令时设置的标志。大多数高级语言不允许您直接访问这些标志。许多处理器的指令格式如下:

cmp a, b
该指令从a中减去b并丢弃差值,但记住了几个描述减法的标志:结果是零吗(零标志)?是否发生借用(借用标志)?结果是否为阴性(符号标志)?是否发生溢出(溢出标志)

compare指令要求被比较的两个对象是相同的类型(两个的补码或无符号),但它不关心哪种类型。稍后可以根据类型检查标志的特定组合来测试结果。也就是说,标记中记录的信息可以根据进行的测试来区分一个2的补码是否大于另一个,或者一个无符号数是否大于另一个。存在测试所需标志属性的条件分支指令

执行算术运算时,通常不需要“反求”数字。处理器包括处理两个补码的算术指令。通常,加法和减法指令是类型不可知的,与比较指令相同,但乘法和除法指令不是(除了返回部分结果的某些乘法形式)。加法和减法指令可以是类型无关的,因为算术运算中发生的换行既适用于补码指令,也适用于无符号指令。然而,这种包装不适用于乘法和除法