c语言溢出问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言溢出问题相关的知识,希望对你有一定的参考价值。
A、#include
void main()
short a,b;
a=32767;
b=a+1;
printf("a=%d,b=%d\n",a,b);
short取值范围:-32768-32767
输出结果为:
a=32767;b=-32768;
B、#include
void main()
unsigned short a=65536;
int b;
printf("%d\n",b=a);
unsigned shord取值范围:0-65535;
输出结果为:0
我有点不明白,为什么A结果和B结果有这么大的差距啊,
到底溢出是怎么回事啊,
为什么A溢出是负数,而B溢出是0啊?
不太明白,能讲讲吗???
对于负数,补码是原码的符号位不变,数值部分按位取反再加1。
short型数据是16位表示最高位是符号位,所以只有15位表示数值,15位000000000000000-111111111111111表示的范围是0-32767,又加上最高位的符号位(第16位),就可以表示-32768-32767 。unsigned short型数据是16位都用来表示数值,16位0000000000000000-1111111111111111表示的范围是0-65535。
计算机在进行计算时是用补数计算的,且如果溢出会进行丢位处理。如short型32767补码是0111111111111111 加1后为1000000000000000(注意最高位是符号位),1000000000000000正是-32768的补数。
而unsigned short型数据无符号65535为1111111111111111(16位),加1后为10000000000000000(17位)这时计算机判断溢出后丢弃第17位,变为0000000000000000就是0了^_^ 参考技术A
需要准备的材料分别有:电脑、C语言编译器。
1、首先,打开C语言编译器,新建一个初始.cpp文件,例如:test.cpp,输入问题基础代码。
2、在test.cpp文件中,将int全部调整为long long,printf函数调整为:printf("%lld!=%lld\\n",n,count);。
3、编译器运行test.cpp文件,此时成功打印出了大数。
参考技术B 以c中同一类型运算,结果仍然是这个类型,由于a与1都是int,所以a+1结果仍然是int,此时就发生了溢出,赋值到b中也是溢出后的值。而当一个int与一个long运算时,结果的类型是long,1l后面的l就是long类型的意思,所以a+1l是int与long运算,得到的也是long,然后赋值到b,所以是正确结果 参考技术C 如果溢出了默认为下界值C语言之溢出
源代码
/**
*********************************************************************
* @file overflow.c
* @author Zhen Haiyang
* @version 1.0
* @date 2021-06-02 23:37:15
* @brief 验证溢出问题
*********************************************************************
*/
#include <stdio.h>
int main()
unsigned int x = 0xF0000000;
printf("%u\\n", x);
unsigned long long y = (unsigned long long)x * 2;
printf("%llu\\n", y);
y = x * 2;
printf("%llu\\n", y);
return 0;
输出结果
4026531840
8053063680
3758096384
分析
c语言中的类型转换方式为:
- 整形运算总是至少按照整数类型(int)的精度进行的。也就是说,若两个char类型的加法的运算过程可以分解为:先将两个char类型转换为int型,计算结果存储为int型,最后强转为char类型存储。
- 如果两个运算数的精度有一个超过int型。若两个操作数属于不同类型,那么,将运算将两个运算数都转换成高精度类型再参与运算。若两个操作数为相同类型,即使是乘法,还是会按照相同类型计算存储结果。这就是可能会造成溢出现象,需要注意。
以上是关于c语言溢出问题的主要内容,如果未能解决你的问题,请参考以下文章