我使用2'补码来表示二进制形式的负数
案例1:数字-5
根据2'补充技术:
将5转换为二进制形式:
00000101然后翻转位
11111010,然后加1
00000001
Run Code Online (Sandbox Code Playgroud)
=>结果: 11111011
为了确保这是正确的,我重新计算到十进制:
-128 + 64 + 32 + 16 + 8 + 2 + 1 = -5
Run Code Online (Sandbox Code Playgroud)
案例2:数字-240
采取相同的步骤:
11110000
00001111
00000001
00010000 => recalculate this I got 16, not -240
Run Code Online (Sandbox Code Playgroud)
我误会了什么?
自从我上次在位和字节级别进行编程以来,已经很长时间了,并且想要确认那些日子我似乎记得的东西:
假设我有两个相等长度的整数(1,2,4,8个字节;无所谓),我将它们加起来:如果它们是有符号或无符号的,则总和的逐位结果是否不同.换句话说:无论它们是有符号整数还是无符号整数,这些位最终都是相同的吗?
我的直觉和脆弱的记忆告诉我他们会,但我只想确认一下.谢谢.
检测架构是否在C++中使用一个或两个补码表示的最可靠方法是什么?
我正在观看David Malan(这里)的一些很棒的讲座,这些讲座已经过了二元版.他谈到签名/未签名,1的赞美和2的补充表示.还增加了4 +( - 3),排列如下:
0100
1101 (flip 0011 to 1100, then add "1" to the end)
----
0001
Run Code Online (Sandbox Code Playgroud)
但他挥挥手,挥动了最后一根手.我做了一些维基百科的研究并没有得到它,有人可以向我解释为什么特定的携带(在8的 - > 16的列中)被丢弃了,但他保留了它之前的那个?
谢谢!
我有一个负整数(4个字节),我希望它的二进制补码表示形式的十六进制形式.
>>> i = int("-312367")
>>> "{0}".format(i)
'-312367'
>>> "{0:x}".format(i)
'-4c42f'
Run Code Online (Sandbox Code Playgroud)
但我想看看"FF ......"
由于SE 7 Java允许将值指定为二进制文字.文档告诉我'byte'是一种可以保存8位信息的类型,值为-128到127.
现在我不知道为什么,但我不能定义8位但只有7如果我尝试将二进制文字分配给Java中的一个字节,如下所示:
byte b = 0b000_0000; //solves to the value 0
byte b1 = 0b000_0001; //solves to the value 1
byte b3 = 0b000_0010; //solves to the value 2
byte b4 = 0b000_0011; //solves to the value 3
Run Code Online (Sandbox Code Playgroud)
依此类推,直到我们使用这7位获得最后几种可能性:
byte b5 = 0b011_1111; //solves to the value 63
byte b6 = 0b111_1111; //solves to the value 127
Run Code Online (Sandbox Code Playgroud)
如果我想让它成为负数我必须添加一个领先 - 在这样的前面:
byte b7 = -0b111_1111; //solves to the value -127
Run Code Online (Sandbox Code Playgroud)
现在问题的一半是我只使用7位来描述他们告诉我的是8位数据类型.下半部分是他们似乎没有线程作为二进制补码,除非使用32位int类型,我可以定义所有32位(包括"符号指示位").
现在,当我搜索如何显示范围内的数字-128时,我被告知这样做,没有任何进一步的解释:
byte b8 = 0b1111_1111_1111_1111_1111_1111_1000_0000;
Run Code Online (Sandbox Code Playgroud)
我可以清楚地看到最后8位(1000 0000)在使用8位的两个强制中确实代表-128,但我从来没有被混淆过多并尝试提出我的问题:
我想用英特尔I64汇编程序做一些长整数数学运算(128位),需要创建一个2的补码.让我们说我的正面价值在于RDX:RAX.
2的补码是通过"翻转位并加1"来完成的.所以最天真的实现是(4条指令和14个字节的代码):
NOT RAX
NOT RDX
ADD RAX,1 ; Can't use INC, it doesn't set Carry
ADC RDX,0
Run Code Online (Sandbox Code Playgroud)
当我在RAX而不是NOT上使用NEG指令时,它对我来说是"+1"但是Carry是错误的,当RAX为零时NEG RAX清除了Carry,但是我需要携带JUST IN THIS CASE.所以下一个最好的方法可能是(4条指令和11个字节的代码):
NOT RDX
NEG RAX
CMC
ADC RDX,0 ; fixed, thanks lurker
Run Code Online (Sandbox Code Playgroud)
还有4条说明.但是不是加+1,我可以减去-1,因为SBB将Carry-Bit加到减数上,当Carry清零时我会加+1.所以我的下一个最好的尝试是这个,有3个指令和10个字节的代码:
NOT RDX
NEG RAX
SBB RDX,-1
Run Code Online (Sandbox Code Playgroud)
从我冗长的文字中可以看出,这一点并不明显.是否有一种更好,更易理解的方法来在汇编程序中进行级联2的补码?
我已经看到了这本书将以下代码计算机系统:一个程序员的角度来看,2/E.这很好用,并创建所需的输出.输出可以通过有符号和无符号表示的区别来解释.
#include<stdio.h>
int main() {
if (-1 < 0u) {
printf("-1 < 0u\n");
}
else {
printf("-1 >= 0u\n");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
-1 >= 0u但是,上面的代码产生的代码与上面的代码相同,不是!换一种说法,
#include <stdio.h>
int main() {
unsigned short u = 0u;
short x = -1;
if (x < u)
printf("-1 < 0u\n");
else
printf("-1 >= 0u\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
收益率-1 < 0u.为什么会这样?我无法解释这一点.
请注意,我已经看到像类似的问题这样,但他们不帮助.
PS.正如@Abhineet所说,这种困境可以通过改变short来解决int.但是,怎么能解释这种现象呢?换句话说,-14个字节是0xff ff ff ff2个字节0xff ff.鉴于它们被解释为2s补码 …
c bit-manipulation integer-promotion twos-complement unsigned-integer
最近我学会了在基础二系统中表示正整数和负整数的两种恭维方法.然后,我尝试使用带有以下短代码的java来实现此操作:
int a=2147483647;
System.out.println("a: "+a);
System.out.println("a+1: "+(a+1));
short b=32767;
System.out.println("b: "+b);
System.out.println("b+1: "+(b+1));
Run Code Online (Sandbox Code Playgroud)
哪个输出:
a:2147483647
a + 1:-2147483648
b:32767
b + 1:32768
这让我感到困惑,因为我认为b + 1,以二进制表示为011111111111111,将变为1000000000000000或十进制,-32768.这是怎么回事?
我正在阅读2 的补码提议的修订版4 (由C ++ 20通过),我有一些疑问。
在引言中说:
像a + bvs中一样,这真的意味着“不可交换” b + a吗?还是应该读成“非关联”?
它还说:
自从开始以来,难道没有以这种方式很好地定义有符号到无符号的转换吗?那应该读为“从无符号转换为有符号”吗?
更改列表中是否还有其他遗漏或错误陈述的内容?