user-0 提问: 无符号算术运算 没有所谓的“溢出”-说  怎么理解阿 ？

回复:
user: user-1
content: 引用 16 楼 FrankHB1989 的回复:这个只是考虑大部分实现的说法，看来也不是每个实现都有这个保证。 大概是因为有符号数的情况可能更复杂（不同体系结构处理的花样更多），语言的抽象对有符号数和无符号数区别对待：只有无符号数无溢出，有符号数可以溢出UB。 ++ 嗯，应该是这样

user: user-2
content: 无符号运算 ，取2^n的模，可以保证低n位值正确~

user: user-1
content: 数的域是数学上群论的概念。

user: user-3
content: 引用 9 楼 lm_whales 的回复:引用 8 楼 xwhbwas2008 的回复:[quote=引用 7 楼 skyliuxu 的回复:] 从哪看的“无符号算术运算 没有所谓的“溢出”-说 ：所有的无符号运算都是以2的n次方为模，这里的n是结果中的位数”？C traps and pitfalls 这其实有两种数的概念在里面 1）是我们平时使用的，数学上的无限域的数的概念，这样其实无符号数就是自然数。 2）计算机上，各种编程语言实现的，模2域中的无符号数；    这个数域中的数+，-，* ，结果总是在模2域中；    这样，也就没有溢出的说法了。 3）模2域中的计算结果，用作现实的自然数，整数    当自然数的+，-，* 结果过大，超出模2域的表示范围；    再用模2域表示，就会有数据丢失现象，这就是溢出。    另外，自然数相减，结果未必是自然数（成了负数，这应该在整数域计算），    结果，用模2域的无符号数表示，结果也是错误的，这也应该是一种溢出。 PS： 溢出，是相对，无限域的整数，来说的。  对于模2域中的无符号数，+，-，* 三种运算； 结果是封闭的，结果是在模2域中。  这样相对于 nBits 的模2域，无符号数+，-，* 三种运算，确实没有溢出的问题。 至于除法，也只有除数为0，这一点有问题。 [/quote] 这个只是考虑大部分实现的说法，看来也不是每个实现都有这个保证。 大概是因为有符号数的情况可能更复杂（不同体系结构处理的花样更多），语言的抽象对有符号数和无符号数区别对待：只有无符号数无溢出，有符号数可以溢出UB。

user: user-3
content: 无符号数所谓的算术运算严格意义上不是一般的整数算术，是以2^n回绕的模算术，所有计算结果都在预期范围内，当然不存在溢出的情况。

user: user-4
content: 引用 9 楼 lm_whales 的回复:引用 8 楼 xwhbwas2008 的回复:[quote=引用 7 楼 skyliuxu 的回复:] 从哪看的“无符号算术运算 没有所谓的“溢出”-说 ：所有的无符号运算都是以2的n次方为模，这里的n是结果中的位数”？C traps and pitfalls 这其实有两种数的概念在里面 1）是我们平时使用的，数学上的无限域的数的概念，这样其实无符号数就是自然数。 2）计算机上，各种编程语言实现的，模2域中的无符号数；    这个数域中的数+，-，* ，结果总是在模2域中；    这样，也就没有溢出的说法了。 3）模2域中的计算结果，用作现实的自然数，整数    当自然数的+，-，* 结果过大，超出模2域的表示范围；    再用模2域表示，就会有数据丢失现象，这就是溢出。    另外，自然数相减，结果未必是自然数（成了负数，这应该在整数域计算），    结果，用模2域的无符号数表示，结果也是错误的，这也应该是一种溢出。 PS： 溢出，是相对，无限域的整数，来说的。  对于模2域中的无符号数，+，-，* 三种运算； 结果是封闭的，结果是在模2域中。  这样相对于 nBits 的模2域，无符号数+，-，* 三种运算，确实没有溢出的问题。 至于除法，也只有除数为0，这一点有问题。 [/quote] 取模就等于是溢出处理，有必要纠结于文字游戏？C traps and pitfalls哪一章哪一节这么说的？ ps:不要太相信翻译的书，要看原版求证

user: user-5
content: 11点加2个小时就是1点 这就是“溢出”也是“取模”

user: user-6
content: 文字游戏 对2的n次方取模本身就是溢出

user: user-1
content: 引用 8 楼 xwhbwas2008 的回复:引用 7 楼 skyliuxu 的回复:从哪看的“无符号算术运算 没有所谓的“溢出”-说 ：所有的无符号运算都是以2的n次方为模，这里的n是结果中的位数”？C traps and pitfalls 这其实有两种数的概念在里面 1）是我们平时使用的，数学上的无限域的数的概念，这样其实无符号数就是自然数。 2）计算机上，各种编程语言实现的，模2域中的无符号数；    这个数域中的数+，-，* ，结果总是在模2域中；    这样，也就没有溢出的说法了。 3）模2域中的计算结果，用作现实的自然数，整数    当自然数的+，-，* 结果过大，超出模2域的表示范围；    再用模2域表示，就会有数据丢失现象，这就是溢出。    另外，自然数相减，结果未必是自然数（成了负数，这应该在整数域计算），    结果，用模2域的无符号数表示，结果也是错误的，这也应该是一种溢出。 PS： 溢出，是相对，无限域的整数，来说的。  对于模2域中的无符号数，+，-，* 三种运算； 结果是封闭的，结果是在模2域中。  这样相对于 nBits 的模2域，无符号数+，-，* 三种运算，确实没有溢出的问题。 至于除法，也只有除数为0，这一点有问题。

user: user-0
content: 引用 7 楼 skyliuxu 的回复:从哪看的“无符号算术运算 没有所谓的“溢出”-说 ：所有的无符号运算都是以2的n次方为模，这里的n是结果中的位数”？C traps and pitfalls

user: user-7
content: 。。。感觉已经很好理解了  好比4位的无符号数 0到15 那么8+8=0

user: user-1
content: 1）计算机上，某个编程语言实现的运算，都是有限域的运算。  1.1）通常就是就是模2域的运算 1.2）模2域有两种类型的运算 1.2.1）第1种就是，计算机上的，普通算术运算。 1.2.2）第2种，是模2域的多项式运算，这种运算用于加密，解密，编码，解码，CRC等。 2）而数学上的，日常应用的，算术运算，都是无限域的算术运算。 3）因为数学上的，日常应用的数，是没有范围限制的，是无限的，    计算机表示的某种类型的数是有限的。    计算机的运算结果，如果超出所能表示范围，结果就不正确了；    这样计算机的运算结果，就出错了；    这种错误，就称为数据溢出错误，简称溢出。

user: user-8
content: 仅供参考： //有符号整形a和b,如何判断a+b是否溢出 #include <stdio.h> int ifo_add(int a,int b) {     __asm {         mov eax,a         add eax,b         jo  overflowed         xor eax,eax         jmp no_overflowed overflowed:         mov eax,1 no_overflowed:     } } int main() {     int a,b;      a=          1;b= 2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a=         -1;b=-2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a= 2147483647;b= 1;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a=-2147483647;b=-1;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a=-2147483647;b=-2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b)); } //          1+( 2) 0 //         -1+(-2) 0 // 2147483647+( 1) 1 //-2147483647+(-1) 0 //-2147483647+(-2) 1  //无符号整形a和b,如何判断a+b是否溢出 #pragma warning(disable:4035) #include <stdio.h> int ifo_addu(unsigned int a,unsigned int b) {     __asm {         mov eax,a         add eax,b         jo  overflowed         xor eax,eax         jmp no_overflowed overflowed:         mov eax,1 no_overflowed:     } } int ifc_addu(unsigned int a,unsigned int b) {     __asm {         mov eax,a         add eax,b         jc  carried         xor eax,eax         jmp no_carried carried:         mov eax,1 no_carried:     } } int main() {     unsigned int a,b;      a=          1u;b= 2u;printf("%11u+(%2u) %d\n",a,b,ifo_addu(a,b));     a= 4294967295u;b= 1u;printf("%11u+(%2u) %d\n",a,b,ifo_addu(a,b));     a=          1u;b= 2u;printf("%11u+(%2u) %d\n",a,b,ifc_addu(a,b));     a= 4294967295u;b= 1u;printf("%11u+(%2u) %d\n",a,b,ifc_addu(a,b));      return 0; } //          1+( 2) 0 // 4294967295+( 1) 0 //          1+( 2) 0 // 4294967295+( 1) 1 //

user: user-1
content: 有溢出，不过如果限定，只能得到可表示数据，那也可以看作没有溢出。  事实上，CPU 做无符号加法运算，溢出后，进位位 c,会置位为1. 但是如果把无符号数，看作模2域中的数，自然就没有溢出一说了。  从模2域的加法的定义看，这个溢出部分,被模2^n 的求余算法，消除了。 而实际计算，CPU只需要，做个简单的加法，就实现了模2^n的加法。（n=8,16,32,64,etc) 其他运算也是类似。

user: user-9
content: 俺也不明白，求高手指教

user: user-4
content: 从哪看的“无符号算术运算 没有所谓的“溢出”-说 ：所有的无符号运算都是以2的n次方为模，这里的n是结果中的位数”？

user: user-10
content: 说的很明白啊，2的n次方的模，nn是结果中的位数。。这还不懂么？