C语言中关于INT_MIN宏的一些问题

7 篇文章 0 订阅
7 篇文章 0 订阅
在进行数据表达和运算的时候,二进制补码表示法是非常直观和快捷的,但是在数的上下界时往往会出现问题,这需要我们特别注意。例如在C语言的头文件<limits.h>里面看到
   #define INT_MAX        2147483647
   #define INT_MIN       (-INT_MAX-1)

在这里,INT_MIN 为什么不写成 -2147483648,-2147483648是一个常量表达式,而不是一个常量。所以-2147483648被理解为一个“-”号和一个常量值2147483648。对于“-”,是对原值补码进行“取反加1”操作。最小的整形数数值是-2147483648。他的相反数就是2147483648,但是这个正数是溢出的,超出了有符号常量的表示范围,整型数的范围是在INT_MIN到INT_MAX之间。由int开始,因为2147483648超过了int的最大取值范围2147483647,所以变成了unsigned long int或long long int,而写成-2147483647 - 1则可以精确的表示成为32位有符号整数的最小值。按照C语言的表达式求值规则,原本可能使用的x < INT_MIN这样的表达式,x被转换为long int类型再进行表达式求值了,便有可能会出现一些预料之外的结果,而按照-2147483647-1这样的定义,不会被认为是long int类型的。

    由此可见,在gcc下运行下面程序出现意料之外的结果也不足为奇了。
  
#include <stdio.h>
#include <limits.h>

int main()
{
    int i = INT_MIN;
    printf("%d",-i);
    return 0;
}

返回结果是:-2147483648。

我们可以认为上面的结果是有负溢出产生的。负溢出指的是,当两个负数相加的时候,如果因为溢出而导致结果是0或者正数。
按照这个加法原理,INT_MIN+INT_MIN=0。

如果从二进制代码的角度考虑,比如两个8位数相加:
  10000000
+ 10000000
=100000000
由于结果超出了8位,这时候第九位会被截去,结果就是0。

参考学长博客——http://toqianmo.sinaapp.com/2013/01/17/tanjiucyuyanbiaozhunkulimits-hguanyuint_minhongdeqiguaidingyi.html | 浅墨淡痕

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值