c语言---数值的上溢和下溢

short、int、long 占用的字节数不同,所能表示的数值范围也不同。
以32位平台为例,下面是它们的取值范围:

数据类型     所占字节数         取值范围
short             2         -32768~32767,即 -215~(215-1)
unsigned short     2         0~65535,即 0~(216-1)
int             4         -2147483648~2147483647,即 -231~(231-1)
unsigned int     4         0~4294967295,即0~(232-1)
long             4         -2147483648~2147483647,即 -231~(231-1)
unsigned long     4         0~4294967295,即0~(232-1)

 在C语言中, signed char 类型的范围为-128~127,而不是-127~127
-128的原码:1 1000 0000 ,9位,最高位符号位,
再算它的反码:1 0111 1111,进而,补码为: 1 1000 0000,这是-128的补码
-128的原码和-0(1000 000)的原码是不同的,但是在char 型中,
是可以用1000 000 表示-128的,关键在于char 是8位,
它把-128的最高位符号位1 丢弃了,截断后-128的原码为1000 000 和-0的原码相同,也就是说
1000 0000  和-128丢弃最高位后余下的8位相同,所以才可以用-0 表示-128,
这样,当初剩余的-0(1000 0000),被拿来表示截断后的-128,
因为即使截断后的-128和char 型范围的其他数(-127~127)运算也不会影响结果,
 所以才敢这么表示-128。


#include<stdio.h>

void test()
{
        char c1 = 128;
        unsigned char c2 = 257;
        //short s1 = 65535;
        short s1 = 32768;
        unsigned s2 = 65537;

        printf("%d,%d,%d,%d \n",c1,c2,s1,s2);
        printf("%08x,%08x,%08x,%08x \n",c1,c2,s1,s2);
        char c3 = -128-1;
        printf("%08d,%08x \n",c3,c3);

        unsigned char a = -1;
        printf("%08d,%08x \n",a,a);
}

//-128,1,-32768,65537
//ffffff80,00000001,ffff8000,00010001
//00000127,0000007f
//00000255,000000ff

void test2()
{
    int i = 2147483647,j = -2147483648;
    unsigned int k = 4294967295, l = 0;

    printf("%d %d %d %d \n",i,i+1,j,j-1);
    printf("%u %u %u %u %u\n",k,k+1,k+2,l,l-1);

}

//2147483647 -2147483648 -2147483648 2147483647
//4294967295 0 1 0 4294967295

void test1()
{
    unsigned int un = 3000000000;
    short end = 200;
    long big = 65537;
    
    printf("un =%u and not %d\n",un,un);
    printf("end = %hd and %d\n",end,end);
    printf("big = %ld and not %hd\n",big,big);
}

//un =3000000000 and not -1294967296
//end = 200 and 200
//big = 65537 and not 1


int main()
{
    test();
    return 0;
}


结论

注意高位截断


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值