说说溢算那些事~!你的计算方式溢算了吗?(转)
2015-05-29 12:48
288 查看
游戏快正式上线了,今天发现一个bug,让人哭笑不得。数据计算溢出了;玩家充值的元宝变为了0;这个可是一件大事,毕竟谁都担不起这个责任啊;
来说说原因吧。开发语言是 java 工具是 netbeans ide 8.0.2
玩家对象有一个属性是 gold 是int类型的;
玩家充值的时候计算方式如下.
看上去好像没什么问题是吧。当然以上是模拟的;
如果你经验丰富的话,或以下看出一些端倪,那就是会溢算的;
也许可能你看不出什么问题,我刚开始也没发现什么问题,所以代码就这么写了,那好,我们来模拟一下
好大家猜一猜,这是会输出什么结果????
也许你会回答输出 2 对。没错我也以为会输出 2 ,
可是运行结果为什么是 1 呢?
首先我们分析一下,为什么我们以为会输出 2 ?那么很明显我们把
gold + tempGold
这两个值的计算想当然的以为会变成 long 型 而大于 Integer.MAX_VALUE
然而事实并非这样,我来看看输出结果
在java的机制下 gold + tempGold 相加并非变成 long 型而是负数
看到这里,也许你会嘲笑我,好吧我承认,我确实没有验证过这个问题。好在游戏还没有上线。测试发现问题。
不管这样,现在我发现了这个问题,并且了解到了问题所在。好吧想办法解决呗。
也就是把 int 转变为 long 的问题
测试一下现在的输出结果呢?
这些正确了,,好吧。。犯二的事情结束了。可是发现这里多了一个变量 long tempLGold;属性和操作不是很方便,还有没有更好的操作;
注意后面那个0L
看看输出
结果还是输出1,也许你会嘲笑我有范二了,对我确实犯二 了,,深究才知道 运算符优先级问题。
那好吧再改改
输出
还可以
这下正确的了,,,
来说说原因吧。开发语言是 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
这下正确的了,,,
失足程序员的犯二事情啊。。。 /article/5256747.html
相关文章推荐
- qq邮箱发送
- IP方式下DHCPv6地址协议过程
- 大端、小端判断
- 第11周项目2-摩托车继承自行车和机动车
- java基础整理——父类引用指向子类对象实体的多态
- Java基于socket实现简易聊天室实例
- 博客园博客撰写工具【开源】(可以直接黏贴图片) (转)
- SharePoint PowerShell创建一个GUID
- mac 安装PS出现下载adobe support advisor检测
- 使用sqlmap中tamper脚本绕过waf
- 数据库范式(1NF 2NF 3NF BCNF)
- 事件驱动开发
- jquery.pagination结合jquery.tmpl封装前台分页--纯js实现与后端语言无关--适合所有前台分页情况
- 微信之门-授权接口
- jstl、EL跟OGNL
- hdu3577 Fast Arrangement
- MyEclipse 2015优化技巧
- Unity3D单例管理类
- POj 2041 Constructing Roads
- chrome开发人员工具中出现绿色的矩形框解决