首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无符号整数中的溢出和下溢

无符号整数中的溢出和下溢
EN

Stack Overflow用户
提问于 2020-10-16 02:19:16
回答 2查看 1.5K关注 0票数 1

假设,我试图减去2个无符号整数:

代码语言:javascript
复制
247 = 1111 0111
135 = 1000 0111

如果减去这两个二进制数,我们得到= 0111 000。

这是地下水流,因为我们现在只需要7位??或者这是怎么回事??

EN

回答 2

Stack Overflow用户

发布于 2020-10-16 07:02:53

在无符号减法c = a - b中,每当b大于a时,就会出现欠流现象。

但是,这是一个循环定义,因为执行a < b比较的机器有多少种是通过使用环绕算法减去操作数,然后根据两个操作数和结果检测溢出。

还请注意,在C中,我们不讨论“溢出”,因为没有错误条件:C无符号整数提供了硬件中常见的环绕算法。

因此,考虑到我们有环绕算法,我们可以检测环绕(或溢出,取决于观点)是否发生在减法中。

我们需要的是来自abc的最重要的比特。我们叫他们ABC。由此,溢出V的计算方式如下:

代码语言:javascript
复制
A B C | V
------+--
0 0 0 | 0
0 0 1 | 1
0 1 0 | 1
0 1 1 | 1
1 0 0 | 0
1 0 1 | 0
1 1 0 | 0
1 1 1 | 1

这将简化为

A'B + A'C + BC

换句话说,当以下时间发生无符号减法c = a - b中的溢出时:

  1. a的msb为0,b的msb为1;
  2. a的msb为0,c的msb为1;

H 122b的msb为1,c的msb也为1。H 225G 226

减去247 - 135 = 112显然不是溢出,因为247大于135.应用上述规则,A= 1,B= 0和C=0。表的10行在V列中有0:无溢出。

票数 2
EN

Stack Overflow用户

发布于 2021-07-11 08:29:38

长话短说,这就是当你拥有:

代码语言:javascript
复制
unsigned char n = 255; /* highest possible value for an unsigned char */

n = n + 1; /* now n is "overflowing" (although the terminology is not correct) to 0 */
printf("overflow: 255 + 1 = %u\n", n);
   
n = n - 1; /* n will now "underflow" from 0 to 255; */
printf("underflow: 0 - 1 = %u\n", n);
   
n *= 2; /* n will now be (255 * 2) % 256 = 254; 
        /* when the result is too high, modulo with 2 to the power of 8 is used */ 
        /* for an 8 bit variable such as unsigned char; */
printf("large overflow: 255 * 2 = %u\n", n);   
   
n = n * (-2) + 100; /* n should now be -408 which is 104 in terms of unsigned char. */
                       /* (Logic is this: 408 % 256 = 152; 256 - 152 = 104) */
printf("large underflow: 255 * 2 = %u\n", n);

其结果是(用gcc 11.1,旗标-Wall -Wextra -std=c99编译):

溢流: 255 +1=0下溢:0-1= 255大溢流: 255 *2= 254大下溢: 255 *2= 104

现在,科学版本:上面的评论只是一个正在发生的事情的数学模型。为更好地了解实际发生的情况,适用以下规则:

  1. 整数推广:

当对

整数执行操作时,会提升小于int的整数类型。如果原始类型的所有值都可以表示为int,则将较小类型的值转换为int;否则,将其转换为无符号int。

因此,当计算机执行n = 255; n = n + 1;时,内存中实际发生的情况是:首先,将右侧计算为int (签名),因为根据整数提升规则,结果符合有符号int。所以表达式的右边变成二进制:0b00000000000000000000000011111111 + 0b00000000000000000000000000000001 = 0b00000000000000000000000100000000 ( 32位int)。

  1. Truncation

(32位int )在被分配回8位数字时丢失了最重要的24位。

因此,当0b00000000000000000000000100000000被分配给变量n (它是一个无符号字符)时,32位值被截断为8位值(只有最右边的8位被复制) => n变成0b00000000

每次手术都会发生同样的事情。右侧的表达式计算为有符号的int,而不是截断为8位。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64382042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档