今天无意中发现一个怪事,当时没理解,后来跟网友讨论了才知道原理,是关于int值的加法算法,两段代码如下:

代码1:

    @Test
public void test1() {
int stackLength = ;
int count = ;
try {
while(true){
count++;
stackLength += stackLength; //每次打印的值为0
System.out.println("stackLength="+count+"次:: "+stackLength);
}
} catch (Exception e) {
System.out.println("occur exception!!! stackLength="+stackLength);
}
}

控制台输出结果很奇怪,全都是0,:

stackLength=21719次:: 0
stackLength=21720次:: 0
stackLength=21721次:: 0
stackLength=21722次:: 0
stackLength=21723次:: 0
stackLength=21724次:: 0
stackLength=21725次:: 0

……  由于打印太快,已经计算了2万多次。

代码2:

    @Test
public void test2() {
int stackLength = 1;
int count = 0;
try {
while(true){
count++;
stackLength += 1;
System.out.println("stackLength="+count+"次:: "+stackLength);
}
} catch (Exception e) {
System.out.println("occur exception!!! stackLength="+stackLength);
}
}

控制台打印结果正常,是一个数一个数加上去的:

stackLength=21211次:: 21212
stackLength=21212次:: 21213
stackLength=21213次:: 21214
stackLength=21214次:: 21215
stackLength=21215次:: 21216
stackLength=21216次:: 21217
stackLength=21217次:: 21218
stackLength=21218次:: 21219
stackLength=21219次:: 21220
stackLength=21220次:: 21221
stackLength=21221次:: 21222
stackLength=21222次:: 21223

……

思路

这就很奇怪了,代码1和代码2中,只有一行代码不一样,

在代码1中为stackLength += stackLength;

在代码2中为stackLength += 1;

但是运行2万多次后,结果却大相径庭。后来与网友讨论才明白其中原理如下:

先说  i+=i 吧,二进制运算的知识。
初始值1  就是 0000 0000 0000 0000 0000 0000 0000 0001 ,
加自己就是  0000 0000 0000 0000 0000 0000 0000 0010.
 0000 0000 0000 0000 0000 0000 0000 0010 + 0000 0000 0000 0000 0000 0000 0000 0010 就=2+2  
结果就是 0000 0000 0000 0000 0000 0000 0000 0100 也就是4
一直到31次的时候,

就变成  1000 0000 0000 0000 0000 0000 0000 0000 

这个值是最小负数

因为 int是32位。当最高符号位超出32位,最后两个最大的负数相加的时候,符号位也变成0了,后32位都是0,就是32个0,所以后面就一直是0了。
当是33位时,两个最大负数相加,连33位都变成了0
因为int只能取32位
所以就是0
然后后面就一直是0+0了
 
好了,明白了这个道理,我们来看看是不是这样的,首先把源码改成如下:
例子3:
    @Test
public void test3() {
int stackLength = 1;
int count = 0;
try {
while(true){
count++;
stackLength += stackLength;
System.out.println("stackLength="+count+"次:: "+stackLength);
if(count > 40){
break;
}
}
} catch (Exception e) {
System.out.println("occur exception!!! stackLength="+stackLength);
}
}

控制台打印如预期之中:

stackLength=1次:: 2
stackLength=2次:: 4
stackLength=3次:: 8
stackLength=4次:: 16
stackLength=5次:: 32
stackLength=6次:: 64
stackLength=7次:: 128
stackLength=8次:: 256
stackLength=9次:: 512
stackLength=10次:: 1024
stackLength=11次:: 2048
stackLength=12次:: 4096
stackLength=13次:: 8192
stackLength=14次:: 16384
stackLength=15次:: 32768
stackLength=16次:: 65536
stackLength=17次:: 131072
stackLength=18次:: 262144
stackLength=19次:: 524288
stackLength=20次:: 1048576
stackLength=21次:: 2097152
stackLength=22次:: 4194304
stackLength=23次:: 8388608
stackLength=24次:: 16777216
stackLength=25次:: 33554432
stackLength=26次:: 67108864
stackLength=27次:: 134217728
stackLength=28次:: 268435456
stackLength=29次:: 536870912
stackLength=30次:: 1073741824
stackLength=31次:: -2147483648
stackLength=32次:: 0
stackLength=33次:: 0
stackLength=34次:: 0
stackLength=35次:: 0
stackLength=36次:: 0
stackLength=37次:: 0
stackLength=38次:: 0
stackLength=39次:: 0
stackLength=40次:: 0
stackLength=41次:: 0

java中int算法的有趣现象的更多相关文章

  1. 关于Java中编码集的有趣现象和解释

    这是在整理另一篇博客的时候发现的一个有趣的现象,是这样描述的:我们都知道Java默认使用的是UniCode编码集,我们也知道char类型占用两个字节.所以奇怪的现象又发生了(见代码): @Test p ...

  2. 计算机基础--Java中int char byte的关系

    计算机基础--Java中int char byte的关系 重要:一个汉字占用2byte,Java中用char(0-65535 Unicode16)型字符来存字(直接打印输出的话是字而非数字),当然要用 ...

  3. java中int取值范围是怎么计算的?

    首先jdk中定义int占4个字节 ===> 32位(后面全部的计算都是以此为根据的) 32位就是jvm仅仅给分配32个格子的空间,用以存放数据. 总所周知计算机中用0和1存放数据. 那么,32个 ...

  4. java中int,float,long,double取值范围,内存泄露

    java中int,float,long,double取值范围是多少? 写道 public class TestOutOfBound { public static void main(String[] ...

  5. java中int和Integer比较

    java中int和Integer比较 一,类型区别 我们知道java中由两种数据类型,即基本类型和对象类型,int就是基本数据类型,而Integer是一个class,也习惯把Integer叫做int的 ...

  6. java中int i 会出现i+1i吗

    Java中int是32,范围是-2147483648到2147483647 所以i+1 < i 或者 i-1 > i是会出现的. int i=(int) Math.pow(2, 32); ...

  7. java中int转成String位数不足前面补零

    java中int转成String位数不足前面补零 转载自:http://ych0108.iteye.com/blog/2174134 java中int转String位数不够前面补零 String.fo ...

  8. java中int的最值解析

    java中int的最大值为十进制的2147483647,也就是java能进行操作的最大数值,超出就会显示不正常.针对以下问题进行讨论. 1.最大值为什么是2147483647? java中int类型占 ...

  9. JAVA中int、String的类型转换

    int -> String int i=12345;String s="";第一种方法:s=i+"";第二种方法:s=String.valueOf(i); ...

随机推荐

  1. FileWriter向文件中写入内容

    1.创建fileWriter对象 2.写入文件信息 3.关闭流 必须关闭流,否则将不能写入文件中 /** * * @author Administrator * 文件写入对象的使用 * */ publ ...

  2. vuex实现原理

    一.Store的层次结构 Store,负责管理整个数据访问.修改等: 提高API: State,数据结构: 所有的getters.mutations,全部都注册到store里:结构大概是: { 'xx ...

  3. 关于win10安装javaJDK时遇到的问题

    昨天晚上装了一下javaJDK1.8,在安装成功并且按照教程设置完环境变量之后进入了cmd界面,输入java,java -version都正常显示,但是输入javac却报错:javac不是内部或外部命 ...

  4. C基础学习笔记

    1.C语言运算符优先级: 2.三种循环比较 while.do-while和for三种循环在具体的使用场合上是有区别的,如下: 1).在知道循环次数的情况下更适合使用for循环: 2).在不知道循环次数 ...

  5. 编译darknet出现libpng16.so.16:对‘inflateValidate@ZLIB_1.2.9’未定义的引用

    cd /usr/lib/x86_64-linux-gnu sudo ln -s ~/anaconda/lib/libpng16.so.16 libpng16.so.16 sudo ldconfig## ...

  6. poi读取excel内容工具类

    该工具类可以读取excel2007,excel2003等格式的文件,xls.xlsx文件格式 package com.visolink; import org.apache.poi.hssf.user ...

  7. windows10 vs2017 C++连接MySQL

    安装mysql8.0 x64 创建test数据库,user表,插入数据如下: +----+------+----------+-----------------+ | id | name | pass ...

  8. 牛客网PAT乙级(Basic Level)真题-数素数 (20)

    题目描述 令Pi表示第i个素数.现任给两个正整数M <= N <= 10000,请输出PM到PN的所有素数. 输入描述: 输入在一行中给出M和N,其间以空格分隔. 输出描述: 输出从PM到 ...

  9. j教你如何用erlang-tuple

    元组是用来保存一组数据元素的复合数据类型,其中数据元素是要求为erlang的数据类型,单不一定要是相同的类型,元组使用封闭的花括号{}来定义,里面的元素有逗号隔开. 例如: 1> {1,2,3} ...

  10. 使用mybatis调用存储过程(注解形式和配置文件形式)

    最近在看资料中涉及到mybatis,突然想到mysql中的视图.存储过程.函数.现将在使用mybatis调用mysql的存储过程使用总结下: 使用的环境:mybatis3.4.6,mysql 5.6, ...