说说溢算那些事~!你的计算方式溢算了吗?(转)

简介: 游戏快正式上线了,今天发现一个bug,让人哭笑不得。数据计算溢出了;玩家充值的元宝变为了0;这个可是一件大事,毕竟谁都担不起这个责任啊; 来说说原因吧。开发语言是 java 工具是 netbeans ide 8.

 

游戏快正式上线了,今天发现一个bug,让人哭笑不得。数据计算溢出了;玩家充值的元宝变为了0;这个可是一件大事,毕竟谁都担不起这个责任啊;

来说说原因吧。开发语言是 java 工具是 netbeans ide 8.0.2

玩家对象有一个属性是 gold 是int类型的;

玩家充值的时候计算方式如下.

复制代码
        int gold = 20000;//玩家原有的
        int tempGold = 20000;//玩家现在充值的 if (Integer.MAX_VALUE >= gold + tempGold) { gold = gold + tempGold; } else { gold = Integer.MAX_VALUE; }
复制代码

看上去好像没什么问题是吧。当然以上是模拟的;

如果你经验丰富的话,或以下看出一些端倪,那就是会溢算的;

也许可能你看不出什么问题,我刚开始也没发现什么问题,所以代码就这么写了,那好,我们来模拟一下

复制代码
        int gold = Integer.MAX_VALUE - 1800;//玩家原有的
        int tempGold = 20000;//玩家现在充值的 if (Integer.MAX_VALUE >= gold + tempGold) { gold = gold + tempGold; System.out.println("1"); } else { gold = Integer.MAX_VALUE; System.out.println("2"); }
复制代码

 

好大家猜一猜,这是会输出什么结果????

也许你会回答输出 2 对。没错我也以为会输出 2 ,

可是运行结果为什么是 1 呢?

首先我们分析一下,为什么我们以为会输出 2 ?那么很明显我们把

gold + tempGold

这两个值的计算想当然的以为会变成 long 型 而大于 Integer.MAX_VALUE

然而事实并非这样,我来看看输出结果

复制代码
        int gold = Integer.MAX_VALUE - 1800;//玩家原有的
        int tempGold = 20000;//玩家现在充值的 if (Integer.MAX_VALUE >= gold + tempGold) { gold = gold + tempGold; System.out.println("1"); } else { gold = Integer.MAX_VALUE; System.out.println("2"); } System.out.println(gold + tempGold);
复制代码

 

--- exec-maven-plugin:1.2.1:exec (default-cli) @ game-gamesr ---
1
-2147445449
------------------------------------------------------------------------
BUILD SUCCESS

 

在java的机制下 gold + tempGold 相加并非变成 long 型而是负数

看到这里,也许你会嘲笑我,好吧我承认,我确实没有验证过这个问题。好在游戏还没有上线。测试发现问题。

不管这样,现在我发现了这个问题,并且了解到了问题所在。好吧想办法解决呗。

也就是把 int 转变为 long 的问题

复制代码
        int gold = Integer.MAX_VALUE - 1800;//玩家原有的
        int tempGold = 20000;//玩家现在充值的 long tempLGold = tempGold; if (Integer.MAX_VALUE >= gold + tempLGold) { gold = gold + tempGold; System.out.println("1"); } else { gold = Integer.MAX_VALUE; System.out.println("2"); } System.out.println(gold + tempGold);
复制代码

测试一下现在的输出结果呢?

--- exec-maven-plugin:1.2.1:exec (default-cli) @ game-gamesr ---
2
-2147463649
------------------------------------------------------------------------
BUILD SUCCESS

这些正确了,,好吧。。犯二的事情结束了。可是发现这里多了一个变量 long tempLGold;属性和操作不是很方便,还有没有更好的操作;

复制代码
        int gold = Integer.MAX_VALUE - 1800;//玩家原有的
        int tempGold = 20000;//玩家现在充值的 if (Integer.MAX_VALUE >= gold + tempGold + 0L) { gold = gold + tempGold; System.out.println("1"); } else { gold = Integer.MAX_VALUE; System.out.println("2"); }
复制代码

注意后面那个0L 

看看输出

--- exec-maven-plugin:1.2.1:exec (default-cli) @ game-gamesr ---
1
------------------------------------------------------------------------
BUILD SUCCESS

结果还是输出1,也许你会嘲笑我有范二了,对我确实犯二 了,,深究才知道 运算符优先级问题。

那好吧再改改

复制代码
        int gold = Integer.MAX_VALUE - 1800;//玩家原有的
        int tempGold = 20000;//玩家现在充值的 if (Integer.MAX_VALUE >= 0L + gold + tempGold) { gold = gold + tempGold; System.out.println("1"); } else { gold = Integer.MAX_VALUE; System.out.println("2"); }
复制代码

输出

--- exec-maven-plugin:1.2.1:exec (default-cli) @ game-gamesr ---
2
------------------------------------------------------------------------
BUILD SUCCESS

还可以

复制代码
        int gold = Integer.MAX_VALUE - 1800;//玩家原有的
        int tempGold = 20000;//玩家现在充值的 if (Integer.MAX_VALUE >= gold + tempGold * 1L) { gold = gold + tempGold; System.out.println("1"); } else { gold = Integer.MAX_VALUE; System.out.println("2"); }
复制代码
--- exec-maven-plugin:1.2.1:exec (default-cli) @ game-gamesr ---
2
------------------------------------------------------------------------
BUILD SUCCESS

这下正确的了,,,

 

失足程序员的犯二事情啊。。。


http://www.cnblogs.com/ty408/p/4532969.html
相关文章
【期末不挂科-单片机考前速过系列P6】(第六章:10题速过定时计数器的结构和工作方式例题)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P6】(第六章:10题速过定时计数器的结构和工作方式例题)经典例题盘点(带图解析)
|
1天前
蓝桥杯真题代码记录(最优清零方案
蓝桥杯真题代码记录(最优清零方案
4 0
|
3月前
|
算法 搜索推荐 程序员
第四十六练 请以递归方式实现计算整数列表的和
第四十六练 请以递归方式实现计算整数列表的和
24 2
|
10月前
L1-058 6翻了 (15 分)(while的巧妙使用)
L1-058 6翻了 (15 分)(while的巧妙使用)
44 0
|
5月前
|
机器学习/深度学习 算法 测试技术
C++前缀和算法:合并石头的最低成本原理、源码及测试用例(一)
C++前缀和算法:合并石头的最低成本原理、源码及测试用例
|
5月前
|
算法 测试技术 C#
C++前缀和算法:合并石头的最低成本原理、源码及测试用例(二)
C++前缀和算法:合并石头的最低成本原理、源码及测试用例
|
12月前
|
存储 机器学习/深度学习
二叉树详解一万字(基础版)看着一篇就够了(上))
树的结构是一种非线性的数据结构,它是由n(n>=0)个节点组成的一个有层次的关系集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说他是根朝上,而叶朝下。
69 0
|
12月前
二叉树详解一万字(基础版)看着一篇就够了(下)
对于堆的调整相当于是对数组的一种调整,将数组的首地址传进来,要调整的数组的长度,相当于是退出的循环条件,向下传给进来parent(root),向上传给child(size-1),然后再用一个表示另外一个。将参数传进来之后进行比较,先比较两个孩子,找出小的那个,然后交换较小孩子和双亲节点,在比较左右孩子的时候要保证右孩子也存在才可以进行比较,就是child+1<size,原因就是这里是堆,是完全二叉树
41 0
|
存储 SQL 关系型数据库
覆盖索引这回事算是整明白了
覆盖索引这回事算是整明白了
204 0
覆盖索引这回事算是整明白了
|
机器学习/深度学习 算法
时间空间复杂度的计算(跑路人笔记)
时间空间复杂度的计算(跑路人笔记)
时间空间复杂度的计算(跑路人笔记)