程序员

整数溢出体现的哲学道理

作者:admin 2021-08-18 我要评论

?一、背景 今天一个小伙伴发了一个demo 问结果是啥 为什么 public class WhileTest { public static void main(String[] args) { int i while (true){ if(i 10){...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)
?一、背景

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

public class WhileTest {
 public static void main(String[] args) {
 int i 
 while (true){
 if(i 10){
 System.out.println(i);
}

image.gif

有些回答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 
System.out.println(Integer.MIN_VALUE);

image.gif

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

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

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

那么为什么会酱紫

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

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

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

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

这和钟表很相似

image.png

十二小时表示法的时钟 转到了中午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位字节 从而在控制过程中产生了整数溢出 导致导航系统对火箭控制失效 程序进入异常处理模块 引爆自毁。

image.png

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

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

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

四、延伸4.1 “物极必反”、“否极泰来”

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

物极必反

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

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

否极泰来

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

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

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

可见中国古人的智慧。

4.2 矛盾的对立统一

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

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

4.2 数学函数

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

image.png

三、思考

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

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

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

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

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



本文转自网络,原文链接:https://developer.aliyun.com/article/787295

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • 整数溢出体现的哲学道理

    整数溢出体现的哲学道理

  • Java 防抖动函数的实现

    Java 防抖动函数的实现

  • 解决 Java 闭包不能访问外部变量

    解决 Java 闭包不能访问外部变量

  • 阿里云服务网格ASM助力实现零信任、强

    阿里云服务网格ASM助力实现零信任、强

腾讯云代理商
海外云服务器