无符号算术运算 没有所谓的“溢出”-说 怎么理解阿 ?

方紫涵 2014-01-08 11:27:49
无符号算术运算 没有所谓的“溢出”-说 :所有的无符号运算都是以2的n次方为模,这里的n是结果中的位数


求这个话的解释
...全文
2021 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2014-01-12
  • 打赏
  • 举报
回复
引用 16 楼 FrankHB1989 的回复:
这个只是考虑大部分实现的说法,看来也不是每个实现都有这个保证。 大概是因为有符号数的情况可能更复杂(不同体系结构处理的花样更多),语言的抽象对有符号数和无符号数区别对待:只有无符号数无溢出,有符号数可以溢出UB。
++ 嗯,应该是这样
AndyStevens 2014-01-11
  • 打赏
  • 举报
回复
无符号运算 ,取2^n的模,可以保证低n位值正确~
lm_whales 2014-01-11
  • 打赏
  • 举报
回复
数的域是数学上群论的概念。
FrankHB1989 2014-01-11
  • 打赏
  • 举报
回复
引用 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。
FrankHB1989 2014-01-11
  • 打赏
  • 举报
回复
无符号数所谓的算术运算严格意义上不是一般的整数算术,是以2^n回绕的模算术,所有计算结果都在预期范围内,当然不存在溢出的情况。
skyliuxu 2014-01-11
  • 打赏
  • 举报
回复
引用 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:不要太相信翻译的书,要看原版求证
ForestDB 2014-01-11
  • 打赏
  • 举报
回复
11点加2个小时就是1点 这就是“溢出”也是“取模”
baichi4141 2014-01-10
  • 打赏
  • 举报
回复
文字游戏 对2的n次方取模本身就是溢出
lm_whales 2014-01-10
  • 打赏
  • 举报
回复
引用 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,这一点有问题。
方紫涵 2014-01-10
  • 打赏
  • 举报
回复
引用 7 楼 skyliuxu 的回复:
从哪看的“无符号算术运算 没有所谓的“溢出”-说 :所有的无符号运算都是以2的n次方为模,这里的n是结果中的位数”?
C traps and pitfalls
derekrose 2014-01-08
  • 打赏
  • 举报
回复
。。。感觉已经很好理解了 好比4位的无符号数 0到15 那么8+8=0
lm_whales 2014-01-08
  • 打赏
  • 举报
回复
1)计算机上,某个编程语言实现的运算,都是有限域的运算。 1.1)通常就是就是模2域的运算 1.2)模2域有两种类型的运算 1.2.1)第1种就是,计算机上的,普通算术运算。 1.2.2)第2种,是模2域的多项式运算,这种运算用于加密,解密,编码,解码,CRC等。 2)而数学上的,日常应用的,算术运算,都是无限域的算术运算。 3)因为数学上的,日常应用的数,是没有范围限制的,是无限的, 计算机表示的某种类型的数是有限的。 计算机的运算结果,如果超出所能表示范围,结果就不正确了; 这样计算机的运算结果,就出错了; 这种错误,就称为数据溢出错误,简称溢出。
赵4老师 2014-01-08
  • 打赏
  • 举报
回复
仅供参考:
//有符号整形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
//
lm_whales 2014-01-08
  • 打赏
  • 举报
回复
有溢出,不过如果限定,只能得到可表示数据,那也可以看作没有溢出。 事实上,CPU 做无符号加法运算,溢出后,进位位 c,会置位为1. 但是如果把无符号数,看作模2域中的数,自然就没有溢出一说了。 从模2域的加法的定义看,这个溢出部分,被模2^n 的求余算法,消除了。 而实际计算,CPU只需要,做个简单的加法,就实现了模2^n的加法。(n=8,16,32,64,etc) 其他运算也是类似。
羽飞 2014-01-08
  • 打赏
  • 举报
回复
俺也不明白,求高手指教
skyliuxu 2014-01-08
  • 打赏
  • 举报
回复
从哪看的“无符号算术运算 没有所谓的“溢出”-说 :所有的无符号运算都是以2的n次方为模,这里的n是结果中的位数”?
独孤九剑贰 2014-01-08
  • 打赏
  • 举报
回复
说的很明白啊,2的n次方的模,nn是结果中的位数。。这还不懂么?

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧