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

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

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

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

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

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

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

 

  1.  int gold = 20000;//玩家原有的 
  2. int tempGold = 20000;//玩家现在充值的 
  3.  
  4. if (Integer.MAX_VALUE >= gold + tempGold) { 
  5. gold = gold + tempGold; 
  6. else { 
  7. gold = Integer.MAX_VALUE; 
  8. }

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

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

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

 

  1.  int gold = Integer.MAX_VALUE - 1800;//玩家原有的 
  2. int tempGold = 20000;//玩家现在充值的 
  3. if (Integer.MAX_VALUE >= gold + tempGold) { 
  4. goldgold = gold + tempGold; 
  5. System.out.println("1"); 
  6. } else { 
  7. gold = Integer.MAX_VALUE; 
  8. System.out.println("2"); 

 

 

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

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

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

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

gold + tempGold

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

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

 

  1. nt gold = Integer.MAX_VALUE - 1800;//玩家原有的 
  2. int tempGold = 20000;//玩家现在充值的 
  3. if (Integer.MAX_VALUE >= gold + tempGold) { 
  4. gold = gold + tempGold; 
  5. System.out.println("1"); 
  6. else { 
  7. gold = Integer.MAX_VALUE; 
  8. System.out.println("2"); 

 

 

  1. --- exec-maven-plugin:1.2.1:exec (default-cli) @ game-gamesr --- 
  2. 1 
  3. -2147445449 
  4. ------------------------------------------------------------------------ 
  5. BUILD SUCCESS 

 

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

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

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

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

 

  1. int gold = Integer.MAX_VALUE - 1800;//玩家原有的 
  2. int tempGold = 20000;//玩家现在充值的 
  3. long tempLGold = tempGold; 
  4. if (Integer.MAX_VALUE >= gold + tempLGold) { 
  5. gold = gold + tempGold; 
  6. System.out.println("1"); 
  7. else { 
  8. gold = Integer.MAX_VALUE; 
  9. System.out.println("2"); 
  10. System.out.println(gold + tempGold); 

 

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

 

  1. --- exec-maven-plugin:1.2.1:exec (default-cli) @ game-gamesr --- 
  2. 2 
  3. -2147463649 
  4. ------------------------------------------------------------------------ 
  5. BUILD SUCCESS 

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

  1. nt gold = Integer.MAX_VALUE - 1800;//玩家原有的 
  2. int tempGold = 20000;//玩家现在充值的 
  3. if (Integer.MAX_VALUE >= gold + tempGold + 0L) { 
  4. gold = gold + tempGold; 
  5. System.out.println("1"); 
  6. else { 
  7. gold = Integer.MAX_VALUE; 
  8. System.out.println("2"); 

注意后面那个0L

看看输出

 

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

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

那好吧再改改
 

 

  1. int gold = Integer.MAX_VALUE - 1800;//玩家原有的 
  2. int tempGold = 20000;//玩家现在充值的 
  3. if (Integer.MAX_VALUE >= 0L + gold + tempGold) { 
  4. gold = gold + tempGold; 
  5. System.out.println("1"); 
  6. else { 
  7. gold = Integer.MAX_VALUE; 
  8. System.out.println("2"); 

输出

 

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

还可以

  1. int gold = Integer.MAX_VALUE - 1800;//玩家原有的 
  2. int tempGold = 20000;//玩家现在充值的 
  3. if (Integer.MAX_VALUE >= gold + tempGold * 1L) { 
  4. gold = gold + tempGold; 
  5. System.out.println("1"); 
  6. else { 
  7. gold = Integer.MAX_VALUE; 
  8. System.out.println("2"); 
  1. nt gold = Integer.MAX_VALUE - 1800;//玩家原有的 
  2. int tempGold = 20000;//玩家现在充值的 
  3. if (Integer.MAX_VALUE >= gold + tempGold * 1L) { 
  4. gold = gold + tempGold; 
  5. System.out.println("1"); 
  6. else { 
  7. gold = Integer.MAX_VALUE; 
  8. System.out.println("2"); 
  9. }

 

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

这下正确的了,,,

 

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

责任编辑:chenqingxiang 来源: 博客园
相关推荐

2022-07-19 13:31:18

Buddy算法内存管理框架

2009-07-29 10:36:04

北电收购

2024-04-03 09:50:33

MySQLMDL事务

2015-07-06 11:35:07

预装软件

2012-11-12 15:19:52

溢信科技内网安全

2016-05-19 18:33:31

百合网云计算婚恋

2010-11-30 14:22:11

溢信科技

2015-06-19 13:54:49

2012-07-25 09:56:16

虚拟化

2017-01-19 20:37:58

office word漏洞下溢

2015-07-23 09:30:43

烂代码程序员

2018-09-27 05:31:14

2011-09-05 17:18:28

2011-10-19 19:07:30

溢信科技安全服务

2018-01-04 13:29:13

租房租房网站安全

2010-08-09 13:20:36

Flex

2010-12-23 15:48:28

内网安全

2017-11-03 13:43:24

云计算Saas信息化

2011-04-14 14:23:06

软件测试测试

2015-03-27 15:07:55

云计算IaaS平台Docker
点赞
收藏

51CTO技术栈公众号