int型溢出问题

article/2025/5/1 19:32:00

目录

  • 问题
  • 原理
    • 奇怪的循环
    • 计算机的编码
    • 循环的产生
  • 如何识别溢出
    • 乘法
    • 加法
  • 参考文献

问题

在执行乘法时( i ! ∗ 2 i , ( i = 0 , 1 , . . . , n − 1 ) i!*2^{i},(i=0,1,...,n-1) i!2i,(i=0,1,...,n1)),当计算的值超过了int上限后却变成了负数。

在这里插入图片描述

原理

奇怪的循环

int的范围是:-2147483648~2147483647
如果超出这个范围会出现循环;也就是最大的数+1变成了最小的数,最小的数-1又成了最大的数。所有的数就像模运算一样形成了循环。
如:-2147483648-1=2147483647;2147483647+1=-2147483648
可以看到在INT_MAX后做累加,就回到了INT_MIN。
在这里插入图片描述

计算机的编码

对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式。上面的循环就是计算机采用的特殊编码造成的。下面分别做介绍。

1,原码
一开始人们是通过原码来表示整数,整数有正负之分,便通过符号位+二进制的方式表示。(最高位(最左边)取0表示正数,取1表示负数。然后加上对应的二进制。)
+1 = 0000 0001
-1 = 1000 0001

2,反码
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反

3,补码
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补

4,为何选择补码
现代的计算机底层是采用补码来对整数编码。这是因为补码能够极大的简化运算。
对于计算机, 加减乘数已经是最基础的运算, 要设计的尽量简单.。于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.

使用原码和反码让符号位也参与计算,都会产生错误
1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2

1 - 1 = 1 + (-1) = [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

而使用补码则不会有这个问题
1-1 = 1 + (-1) = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=0

此外使用补码还能多表示一个负数
0用[0000 0000]表示, 而以前出现问题的-0则不存在了.可以用[1000 0000]表示-128.
这就是为什么现在32位的int范围是-2147483648~2147483647

循环的产生

INT的最大值2147483647的二进制是:
1111111111111111111111111111111
2147483648的二进制是:
10000000000000000000000000000000

换成补码:
0 00000000000000000000000000000000(INTMAX)
0 0111111111111111111111111111111111111(INTMAX+1,溢出了1位)

因为INT只支持32位,就多出来了1位,计算机默认会截除掉最高位(最左边)。
则INTMAX+1的补码就变成了:
0 111111111111111111111111111111111111=-2147483647

计算机巧妙的利用这一点在溢出后达成了一个循环

如何识别溢出

乘法

设int a, b;
ab>INTMAX 显然是无法判断出结果的(溢出了就从负数开始循环)。
换个思路使用b>INTMAX/a
就是把溢出的a
b拆分为未溢出的a和b,然后执行除法来判断是否溢出。
本问题的判断就可以修改如下:

int algo(int n, int a[])
{a[0] = 0;a[1] = 2;for (int i = 2; i < n; i++){a[i] = 2 * i * a[i - 1];//if (a[i-1] > INT_MAX / (2*i))if(0){printf("a[i]:%d\n", i);printf("堆栈上溢,按出错处理!");exit(OVERFLOW);}}return OK;
}

加法

例:检查两个非负整型变量a+b是否溢出
第一种:if(a+b < 0)
这种做法是检查内部寄存器的标志位是否为负

第二种: if((unsigned)a +(unsigned)b >INT_MAX)
这种做法是强制将a和b都强制转换成无符号整数

第三种: if(a > INT_MAX - b)
这种做法不需要用到无符号算术运算符,也和我们之前乘法的处理类似

参考文献

[1]https://blog.csdn.net/weixin_33898233/article/details/92355647.
[2]https://blog.csdn.net/shun_smile/article/details/80042210.
[3]https://blog.csdn.net/zl10086111/article/details/80907428.
[4]https://zhuanlan.zhihu.com/p/340095782.
[5]https://blog.csdn.net/WmxL56/article/details/38380627.
新开通了本人的公众号,欢迎关注:燕南路GISer ,专注GIS干货分享,不定期更新。
主要兴趣:GIS、时空数据挖掘、python、机器学习深度学习
提问、求资源等都可在公众号后台留言
CSDN的部分内容会重写再搬迁到公众号,欢迎关注!
在这里插入图片描述


http://chatgpt.dhexx.cn/article/cjU4ovOO.shtml

相关文章

C++中int型和string型的相互转换

一、int型转string型 1、to_string函数&#xff0c;头文件#include<string> c11标准增加了全局函数std::to_string: string to_string (int val); string to_string (long val); string to_string (long long val); string to_string (unsigned val); string to_s…

ArcGIS:使用栅格计算器修改特定条件下的值,如将小于100的数修改为0

使用ArcGIS中的栅格计算器可以将特定条件的值进行修改&#xff0c;如原来栅格值的范围为10-1000&#xff0c;可以通过条件语句将其修改为10-100。 修改的时候需要用到栅格计算器中的con条件语句&#xff0c;用法如下&#xff1a; con(条件,满足条件的部分赋值赋值,不满足条件的…

arcgis栅格计算器python教程_arcgis栅格计算器的使用

原标题&#xff1a;arcgis栅格计算器的使用 arcgis栅格计算器的使用 栅格计算器的灵活运用可以解决获取的数据的很多问题和应用。 以dem高程数据为例&#xff0c;可以运用栅格计算器可以直接获取坡度坡向等结果&#xff0c;但是很多时候是需要连续计算多次获得想要的结果。 …

arcgis栅格计算器:将栅格图层指定值设置为Nodata及栅格图层求交

1. 首先需要找到栅格计算器的位置 2. 将栅格图层的某个数据设置为Nodata setnull函数可将特定的栅格值赋值为空值 SetNull("这里是栅格图像名称"0 & 4,1)说明&#xff1a; 将栅格图像中0和4的栅格设置为Nodata&#xff0c;并将其他值设置为1。 结果显示&#x…

【ArcGIS风暴】栅格计算器(Raster Calculator)运算出现错误问题及解决方案汇总

栅格计算器(Raster Calculator) 是一种空间分析函数工具,可以输入地图代数表达式,使用运算符和函数来做数学计算,建立选择查询,或键入地图代数语法。只有熟练的运用并记忆一些常用的公式,才能很好的运用栅格计算器。在使用的过程中,容易出现这样那样的问题,本文就把栅…

C# VS2010 ArcEngine 栅格计算器

本来一开始我的想法是把栅格计算器中的几种功能都封装起来&#xff0c;最后拼成栅格计算器的完整功能&#xff0c;但在实践过程中我不得不面对&#xff0c;这样造成的代码的复杂度上升&#xff0c;公式只能一步步计算的问题。最终使用了GP工具中的RasterCalculator。 注意&…

arcgis栅格计算器python教程_ArcGIS教程:栅格计算器

摘要 在类似计算器的界面中&#xff0c;使用Python语法构建和执行单个地图代数表达式。 插图 用法 栅格计算器工具用于创建和执行地图代数表达式以输出一个新的栅格数据。 可在图层和变量列表中选择要用在表达式中的数据集和变量。并且&#xff0c;通过在工具对话框中单击相…

arcgis 利用栅格计算器计算 土地转移矩阵

可以前往“地信遥感数据汇”获取更多数据。 https://www.gisrsdata.com/ 如果你要做土地利用变化的研究&#xff0c;那就会用到土地转移矩阵。而土地利用转移矩阵常规有两个办法。 第一种办法就是利用ENVI里面的change detection statics工具。 第二种办法就是利用arcgis里面…

基于arcgis栅格计算器进行连续时间序列NDVI的Slope趋势分析

一、趋势分析法简介 趋势分析法是一种通过对随时间变化的变量进行线性回归分析&#xff0c;从而来预测其变化趋势的方法。其计算方法如下&#xff1a; 式中&#xff0c;Slope为像元回归方程的斜率&#xff0c;NDVI i为第i年的NDVI的平均值&#xff0c;n为研究的时间长度,视自…

【使用ArcGIS的栅格计算器批量计算波段】

使用ArcGIS的栅格计算器批量计算波段 一、先建立一个模型1.1 创建变量 二、将栅格计算器工具拖进模型里面&#xff0c;将路径安排好。保存模型。三、勾选模型参数。四、在目录里面找到该模型&#xff0c;右键选择 “批处理”五、将这一行选中&#xff0c;粘贴中Excel中六、根据…

ArcGIS 栅格计算器 Con用法

ArcGIS 栅格计算器 Con用法 前言栅格计算器 Con函数用法ArcGIS 案例操作 关注公众号&#xff0c;分享GIS知识、ArcGIS教程、SCI论文与科研日常等 前言 栅格计算器 栅格计算器界面如图&#xff0c;主题包括五部分&#xff1a;1&#xff09;ArcGIS加载的图层&#xff1b;2&…

【ArcGIS】模型构建--保姆级教程|批量掩膜、栅格计算器、裁剪、波段集统计等

问题来源&#xff1a; 在进行数据处理时&#xff0c;我们会需要对多年数据进行处理&#xff0c;或者是一年的多个实相的数据进行处理&#xff0c;那么如何批量、少手动的操作呢&#xff1f; 说在前面&#xff1a; 1&#xff1a;采用的ArcGIS10.0. 2&#xff1a;以批量掩膜提取…

【ArcGIS风暴】ArcGIS10.6栅格计算器(Raster Calculator)用法详解

扩展阅读: 【ArcGIS风暴】ArcGIS 10.2栅格计算器实用公式大全(经典珍藏版) 【ArcGIS风暴】栅格计算器(Raster Calculator)运算出现错误问题及解决方案汇总 文章目录 1. 栅格计算器简介2. 栅格计算器用法3. 简单算术运算4. 数学函数运算5. 空间分析函数运算1. 栅格计算器简…

【ArcGIS自定义脚本工具】批量执行栅格计算器

文章目录 一、功能介绍二、脚本代码三、工具参数四、用例4.1 批量单位换算4.2 批量计算植被覆盖度4.3 批量填充空值 系列文章目录&#xff1a; ArcGIS自定义脚本工具 一、功能介绍 功能 将多个栅格文件按照某以代数表达式执行栅格计算器(Raster Calculator) 工具&#xff0c;并…

ArcGIS ModelBuilder批量栅格计算器

利用ArcGIS的Model Builder批量进行栅格计算 问题描述&#xff1a;利用批量栅格计算器对文件夹中的多张栅格影像的值进行去0处理。 操作步骤&#xff1a; 1、打开ModelBuilder工具&#xff0c;插入“栅格迭代器”&#xff0c;设置输入参数。 图1 ModelBuilder工具位置 图2 …

QGIS栅格数据处理工具(1):栅格计算器

相较于ArcGIS的栅格计算器&#xff0c;QGIS的栅格计算器效率更高&#xff0c;尤其是对于分辨率高的大影像(GF2、GF6)&#xff0c;因此遇到此类问题(如指数反演)我基本上使用QGIS计算。QGIS栅格计算器的语法更接近python的语法&#xff0c;下面选择1景landsat8影像使用QGIS的栅格…

arcGIS python两个栅格数据,栅格计算器进行栅格代数计算。 信息熵(区位熵)计算

arcGIS python两个栅格数据&#xff0c;栅格计算器进行栅格代数计算。 下载链接&#xff1a;多个栅格数据进行代数运算实例demo 信息熵&#xff08;区位熵&#xff09;计算公式&#xff1a; #-*- coding:UTF-8 -*- import arcpy from arcpy import env from arcpy.sa impor…

ArcGIS 栅格计算器con()函数用法

函数的基本语句&#xff1a;con&#xff08;条件&#xff08;语句&#xff09;&#xff0c;真&#xff08;语句&#xff09;&#xff0c;假&#xff08;语句&#xff09;&#xff09; 若“真&#xff08;语句&#xff09;”或“假&#xff08;语句&#xff09;”存在缺失&…

第十五章 栅格数据重分类、栅格计算器、插值分析

文章目录 第十五章 栅格数据分析第一章 栅格数据重分类第一节 栅格数据重分类第二节 栅格重分类的使用第三节 重分类的使用中的空值使用第四节 重分类的案例&#xff1a;分类统计面积第五节 坡度矢量分级图生成 第二章 栅格计算器第一节 栅格计算器介绍第二节 栅格计算器使用第…

ArcGIS栅格计算器

栅格计算是栅格数数据空间分析中数据处理和分析中最为常用的方法,应用非常广泛,能够解决各种类型的问题,尤其重要的是,它是建立复杂的应用数学模型的基本模块。ArcGIS提供了非常友好的图形化栅格计算器,利用栅格计算器,不仅可以方便的完成基于数学运算符的栅格运算,以及…