整数溢出体现的哲学道理

简介: 整数溢出体现的哲学道理

一、背景

今天一个小伙伴发了一个demo,问结果是啥,为什么?


public class WhileTest {

   public static void main(String[] args) {

       int i  = 0;

       while (true){

           i++;

           if(i == 10){

               System.out.println(i);

           }

       }

   }

}

有些回答10,有些回答居然是9.....

小伙伴们运行就会发现,打印了好多次10。



可能很多小伙伴觉得so easy,溢出了呗,负数了呗。

请问哪个负数?最大值+1是几?

能不能清晰地从二进制角度去讲解?

面试官说:if 能  then 能否讲讲体现出啥哲理??


are you kidding me ?咋还扯到哲学了!?


这个面试官惹不起,咱不面了,还是主动回家等消息吧......


二、分析

首先这是单线程(单线程都是顺序执行的),if条件是等于10为真,怎么可能打印出来的是9????


另外的话我们看,初始化是0,然后while循环是恒真的,那么i++会一直执行,当加到10的时候  下面肯定会打印出来的。


那么然后呢??然后一直增加对吧?


那么如果一直增加到整数最大值怎么办??会发生什么???


我们先看下整数最大值如果再+1会怎样?


int i = Integer.MAX_VALUE;

System.out.println(i+1);

System.out.println(Integer.MIN_VALUE);

发现结果是:-2147483648,是负数!!而且是整数的最小值!


因此再一直加1是不是又到了0 然后到10,然后又打印一次对吧,然后继续循环.....


小伙伴们运行就会发现,打印了好多次10。


那么为什么会酱紫??


int 类型在 Java 中是“有符号”的,所谓“有符号”就是有正负。


大家知道计算机中用二进制表示所有的信息,java中整数是4个字节(一个字节8位)即32位,其中首位是符号位,如果是1表示负数,0则表示整数。


但是如果正数过大了,例如 2^31,计算机不得不把首位变成 1,并且很快就忘了这是溢出情况,把它按照正常的方式输出了,于是就成了负的。


其实也不能怪它,它没有办法自动处理超过溢出的情况,因为 32 位是固定的,它不能因为溢出而临时扩展到 33 位之类的。


这和钟表很相似,




十二小时表示法的时钟,转到了中午12点,然后会怎样???


盘面就那么大总不能给你变出个13吧?虽然我们知道是下午1点,但是其盘面的效果和凌晨1点没区别。


2^31 - 1 = 0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647


2^31      = 2^31 - 1 + 1 = 1000 0000 0000 0000 0000 0000 0000 0000 = -2147483648


溢出变成 0 的话道理也一样。你想如果一个数大到最后 32 位都是 0 了,那计算机只能把它认作 0。


这种情况有很多,例如 2^32 就是一共 33 位,首位 1,后面 32 位都是 0。


我们从二进制的角度可以清晰的认识到,2^31 - 1 = 0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647  加一后(二进制逢二进一)确实是整数能表示的最小值     2^31      = 2^31 - 1 + 1 = 1000 0000 0000 0000 0000 0000 0000 0000 = -2147483648。


另外为啥整数的最大值是2的31次方-1,而不是32次方??


因为首位是符号位,因此数据位只有31位。31位全为1才是最大值


那么值为 2^30+2^29+...+2^0 = 2^31-1次。


为啥最小值是2^31?


最小值肯定为负数,则首位为1,那么剩下31位最小的话必定都为0。因此值为1*2^31+0+...+0=2^31。


三、教训

1996年6月4日,阿丽亚娜5型运载火箭(Ariane 5)在法国库鲁的欧洲运载火箭发射场发射,37秒后火箭解体并爆炸。火箭的开发费用大约70亿美元,火箭本体及运载的设备价值约5亿美元。两周后的调查报告指出,爆炸原因由于火箭某段控制程序直接移植自阿丽亚娜4型火箭,其中一个需要接收64位数据的变量为了节省存储空间而使用了16位字节,从而在控制过程中产生了整数溢出,导致导航系统对火箭控制失效,程序进入异常处理模块,引爆自毁。




这都是不细心和基础不扎实惹的祸!


知道为什么面试中爱问各种数据类型的范围了吧?


开发中要选取最合适的数据类型,考虑极端情况,比如整数溢出的问题,订单Id等增长较快的整型要设置为长整型。


四、延伸

4.1 “物极必反”、“否极泰来”

另外让我想到了两个词语“物极必反”、“否极泰来”(虽然不完全一致,思想是一致的)


物极必反

【解释】:极:顶点;反:向反面转化。事物发展到极点,会向相反方向转化。

【出处】:《吕氏春秋·博志》:“全则必缺,极则必反。”《鹖冠子·环流》:“物极则反,命曰环流。”

否极泰来

【解释】否、泰:《周易》中的两个卦名。否:卦不顺利;泰:卦顺利;极:尽头。逆境达到极点,就会向顺境转化。指坏运到了头好运就来了。

【出处】《周易·否》:“否之匪人,不利君子贞,大往小来。”《周易·泰》:“泰,小往大来,吉亨。”《吴越春秋·勾践入臣外传》:“时过于期,否终则泰。


我们整数不断增加到最大值,然后“物极必反”就转化为了负数。我们整数的最小值即“否极”然后不断增加即“泰来”。

可见中国古人的智慧。


4.2 矛盾的对立统一

这点和马克思主义哲学上的“矛盾对立统一”是一致的,矛盾的同一性的第三条就讲到:


矛盾双方在一定条件下相互转化。你能变成我,我能变成你。


4.2 数学函数

这点和数学的一些函数很相似,正弦函数为例(虽然不完全一致,思想是一致的),它是有范围的-1到1,到最高点则会降低。




三、思考

我们遇到问题要从根本上去理解它,而不是仅仅观察这个现象,知道怎么解决这个问题。


另外我们要尝试把各个学科的思想结合在一起帮助自己去理解知识点。


创作不易,如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。


另外欢迎加入我的知识星球,知识星球ID:15165241 一起交流学习。


https://t.zsxq.com/Z3bAiea  申请时标注来自CSDN。

————————————————

版权声明:本文为CSDN博主「明明如月学长」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/w605283073/article/details/92745454

相关文章
|
人工智能 搜索推荐 算法
C语言第十一练——输出本机的C语言基本数据类型最大最小取值范围
C语言第十一练——输出本机的C语言基本数据类型最大最小取值范围
75 0
|
算法 搜索推荐 程序员
C语言第十四练——请输入一个数的逆序数
C语言第十四练——请输入一个数的逆序数
128 0
|
算法 搜索推荐 程序员
C语言第十练——实现求一个数的所有因数
C语言第十练——实现求一个数的所有因数
297 0
|
2月前
|
Java 开发者
【编程基础知识】2的n次幂与二进制位全为1之间的联系,为啥只差一个1
本文深入探讨了2的n次幂与二进制位全为1之间的数学联系,解释了2的n次幂减一的二进制表示为何全为1,并探讨了这一特性在HashMap中的应用。通过基础数学原理和实际代码示例,文章揭示了这一特性的实用价值,适合各水平的编程爱好者学习。
26 3
|
6月前
|
C语言
基于C语言的随机点名器设计
基于C语言的随机点名器设计
基于C语言的随机点名器设计
|
算法 搜索推荐 程序员
C语言第二练——求三个数的最大值
C语言第二练——求三个数的最大值
246 0
|
7月前
|
存储 算法 搜索推荐
C语言第二十七练 异或的运算规律
C语言第二十七练 异或的运算规律
64 0
|
7月前
|
算法 搜索推荐 程序员
C语言第十七练——输出二进制中1的个数
C语言第十七练——输出二进制中1的个数
57 0
|
C语言
一文搞明白整型提升,截断等相关概念【C语言】
一文搞明白整型提升,截断等相关概念【C语言】
|
存储 编译器 C语言
【C语言航路】第十一站:字符串、字符和内存函数(下)
【C语言航路】第十一站:字符串、字符和内存函数
78 0