优秀的编程知识分享平台

网站首页 > 技术文章 正文

C|整数、浮点数的向上、向下溢出

nanyue 2025-01-18 23:01:52 技术文章 5 ℃

正如资源总是有限的,表示二进制的内存单元也总是有限的,这就是所谓的有限字长的二进制表示。

所以,不管是定点数,还是浮点数,其长度总是有限的,总是有向上或向下溢出的可能。

1 整数向上、向下溢出

#include <stdio.h>
#include <limits.h>

void signedIntOverflow()
{
    printf("%d\n",INT_MAX);         // 2147483647
    signed int data = 0x7fffffff;   // (1<<31)-1
    printf("%d\n",data); // 2147483647
    data+=1;
    printf("%d\n",data); // -2147483648
}

void signedIntUnderflow()
{
    printf("%d\n",INT_MIN);         // -2147483648
    signed int data = 0x80000000;   // 1<<31
    printf("%d\n",data); // -2147483648
    data-=1;
    printf("%d\n",data); // 2147483647
}

void unsignedIntOverflow()
{
    unsigned int data = 0xffffffff; // (1<<32)-1
    printf("%u\n",data); // 4294967295
    data+=1;
    printf("%u\n",data); // 0
}

int main()
{
    signedIntOverflow();
    printf("\n");
    signedIntUnderflow();
    printf("\n");
    unsignedIntOverflow();
    getchar();
    return 0;
}

2 浮点数的向上、向下溢出

#include <stdio.h>
void floatNotAccurate()
{
    float d1=2.001;
    float d2=0;
    printf("d1 的初始值:2.001\n");
    for (int i=0; i<1000; i++)
    {
        d2+=d1 ;
    }
    printf("d1加1000次后的值:%10.30f\n",d2);
    // d1 的初始值:2.001
    // d1加1000次后的值:2000.983886718750000000000000000000
}
void floatPrecision()
{
// 1、默认只显示小数点后六位,如果需 要显示更多为,需要通过宽度格式符控 制,
// 2、单精度本系统精度为6位,6位以内 准确表示.
// 3、双精度小数点后15位有效,15位以 内精确表示。
//-------------------------
    double d1=3.1234567890123456789;
    double d2=3.1234567890123452789;
    double d3=1.1234567890123456789; //小数点后15位内能够准确表示,15 位以后无法准确
    double d4=1.1234567890123452789;
    float f1=3.1234567890;
    float f2=3.1234564890;
    float f3=1.1234567890;
    float f4=1.1234564890; //小数点6位内能够准确表示表示,7位以后无法准 确
    printf("查看双精度第16位的四舍五入以及15位以后的数据:\n");
    printf("d1的值:%20.19f\n",d1);
    printf("d2的值:%20.19f\n\n",d2);
    printf("d3的值:%20.19f\n",d3);
    printf("d4的值:%20.19f\n\n",d4);
    printf("查看单精度第6位的四舍五入 以及6位以后的数据:\n");
    printf("f1的值:%20.19f\n",f1);
    printf("f2的值:%20.19f\n\n",f2);
    printf("f3的值:%20.19f\n",f3);
    printf("f4的值:%20.19f\n",f4);
/*
查看双精度第16位的四舍五入以及15位以后的数据:
d1的值:3.1234567890123457000
d2的值:3.1234567890123452000

d3的值:1.1234567890123457000
d4的值:1.1234567890123452000

查看单精度第6位的四舍五入 以及6位以后的数据:
f1的值:3.1234567165374756000
f2的值:3.1234564781188965000

f3的值:1.1234568357467651000
f4的值:1.1234564781188965000
*/
}

void floatUnderFlow()
{
    //如果实际要表示的数要比规格化的1.175494351 e-38 小得多
    //内存表示为0,可通过查看变量值看到
    int i;
    float fmin=1.175494351e-38;
    printf("%.330f\n",1.175494351e-320);
    printf("%.340f\n",1.175494351e-330);
    /*
0.000000000000000000000000000000000000000000000000000000000000000000000000000000 //78
00000000000000000000000000000000000000000000000000000000000000000000000000000000 //80
00000000000000000000000000000000000000000000000000000000000000000000000000000000 //80
00000000000000000000000000000000000000000000000000000000000000000000000000000000 //80
011753821715                                                                     //12
0.000000000000000000000000000000000000000000000000000000000000000000000000000000 //78
00000000000000000000000000000000000000000000000000000000000000000000000000000000 //80
00000000000000000000000000000000000000000000000000000000000000000000000000000000 //80
00000000000000000000000000000000000000000000000000000000000000000000000000000000 //80
0000000000000000000000                                                           //22
*/
}

  
void floatOverflow()
{
    float fmax=3.402823466e+38; //测试上溢 
    printf("fmax=3.402823466e+38\n指数格式输出值:%e\n浮点数输出值:%f\n \n",fmax,fmax);
    fmax=3.4028234e+38; //测试上溢
    printf("fmax=3 .4028234e+38\n指 数格式输出值:%e\n浮点数输出值:%f\n \n",fmax,fmax);
    fmax=3.4028235e+38;//测试上溢
    printf("fmax=3 .4028235e+38\n指 数输出数值:%e\n浮点格式输出值:%f\n \n",fmax,fmax);
    fmax= 3.4028236e+38;//测试上溢
    printf("fmax=3 .4028236e+38\n指 数输出数值:%e\n浮点格式输出值:%f\n \n",fmax,fmax);
    fmax=-3.4028236e+38;//测试上溢
    printf("fmax=-3.4028236e+38\n 指数输出数值:%e\n浮点格式输出值:%f \n\n",fmax,fmax);
/*
fmax=3.402823466e+38
指数格式输出值:3.402823e+038
浮点数输出值:340282346638528860000000000000000000000.000000  // 小数点前39位

fmax=3 .4028234e+38
指数格式输出值:3.402823e+038
浮点数输出值:340282346638528860000000000000000000000.000000

fmax=3 .4028235e+38
指数输出数值:3.402823e+038
浮点格式输出值:340282346638528860000000000000000000000.000000

fmax=3 .4028236e+38
指数输出数值:1.#INF00e+000
浮点格式输出值:1.#INF00

fmax=-3.4028236e+38
 指数输出数值:-1.#INF00e+000
浮点格式输出值:-1.#INF00
*/
}

main()
{
    floatUnderFlow();
    floatOverflow();
    floatNotAccurate();
    floatPrecision();
    getchar();
}

-End-

最近发表
标签列表