计算机使用什么方法添加无符号整数
What method does the computer use to add unsigned integers
int main(){
unsigned int num1 = 0x65764321;
unsigned int num2 = 0x23657432;
unsigned int sum = num1 + num2;
cout << hex << sum;
return 0;
}
如果我有两个无符号整数,则说 num1 和 num2。然后我告诉计算机未签名
int sum = num1 + num2;
计算机用什么方法添加它们,会不会是两个的补充。总和变量是否会打印在 2 的补码中。
就实际位而言,2 的补码加法与无符号加法相同。 在实际的硬件中,设计将是像 https://en.wikipedia.org/wiki/Carry-lookahead_adder 一样复杂的东西,因此它可以是低延迟(不必等待进位波纹到32位或64位,因为对于add
来说,门延迟太多,不能成为单周期延迟。
一个补码和符号/幅度是C++允许实现使用的其他有符号整数表示,它们的环绕行为与无符号不同。
例如,一个人的补码加法必须将带出包装回低位。 请参阅这篇关于优化 TCP 校验和计算的文章,了解如何在仅提供 2 的补码/无符号加法的硬件上实现补码加法。 (特别是 x86(。
C++将符号溢出作为未定义的行为,但真正的补码和符号/量级硬件确实具有特定的记录行为。 将unsigned
位模式reinterpret_cast
为有符号整数会给出一个结果,该结果取决于您运行的硬件类型。 (不过,所有现代硬件都是 2 的补充。
由于无符号或 2 的补码的按位运算是相同的,因此这完全取决于您如何解释结果。 在像 x86 这样的 CPU 体系结构上,根据指令的结果设置标志,溢出标志仅与有符号解释相关,而携带标志仅与无符号解释相关。 硬件从单个指令生成两者,而不是让单独的有符号/无符号添加指令执行相同的操作。
有关无符号携带与签名溢出以及 x86 标志的精彩文章,请参阅 http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt。
在其他架构(如 MIPS(上,没有 FLAGS 寄存器。 您必须使用比较或测试指令来弄清楚发生了什么(进位或零或其他(。add
指令不设置标志。 请参阅此MIPS问答,了解32位MIPS上的64位附加功能。
但是为了检测签名溢出,add
溢出时引发异常(x86 将在其中设置 OF(,因此如果您希望addu
不会在签名溢出时出错,请使用 进行签名或无符号添加。
现在这里的溢出标志是 1(这是我们教练给出的示例(表示有溢出但没有携带,那么这里怎么会有溢出
您有一个C++程序,而不是 x86 汇编语言程序! C++没有携带或溢出标志。
如果您使用非优化编译器为 x86 编译此程序,并且它对您的两个输入使用了ADD
指令,您将从该ADD
指令中获得OF=1
和CF=0
。
但是编译器可能会使用lea edi, [rax+rdx]
在不覆盖任一输入的情况下执行求和,并且LEA
不会设置标志。
或者,如果编译器在编译时进行了添加,则代码的编译方式将与源代码相同,如下所示:
cout << hex << 0x88dbb753U;
并且在运行时不会添加您的数字。 (当然,iostream 库函数中会有很多添加内容,甚至可能在main()
中作为创建堆栈帧的一部分的add
指令,如果您的编译器选择发出设置堆栈帧的代码。
我有两个无符号整数
计算机使用什么方法添加它们
目标 CPU 体系结构上可用的任何方法。大多数都有一个名为 ADD 的指令。
总和变量是否会打印在 2 的补码中。
二进制补码是一种在二进制中表示整数类型的方法。这不是打印数字的方法。
- 如何打印boost多精度128位无符号整数
- C++模板函数,用于比较任何无符号整数和有符号整数
- 在线程中读取无符号整数时,c++ 位是否以原子方式切换?
- Constexpr 可变参数模板,用于对无符号整数进行重新排序
- 为什么 Clang 和 GCC 中两个无符号整数之和的结果类型不同
- 从 std::string 转换为 const 无符号整数
- 迭代器和无符号整数的重载 + 运算符
- C++,概念不适用于无符号整数作为结果类型?
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- 原子式清除无符号整数的最低非零位
- 计算机使用什么方法添加无符号整数
- boost::任何带有结构体和无符号整数
- 添加有符号和无符号整数
- 如何安全地比较两个无符号整数计数器?
- 计算 (64 位无符号整数) * (64 位无符号整数) 的商除以 2^64
- 如何将 32 位无符号整数分配给包含 32 位的位字段
- 如何将以"\0"开头的字符 * 转换为无符号整数?
- *(易失性无符号整数 *) 的含义 0x00 = 0x00;
- 为大无符号整数分配内存的有效方法
- 添加两个有符号或无符号整数