游戲快正式上線了,今天發(fā)現(xiàn)一個(gè)bug,讓人哭笑不得。數(shù)據(jù)計(jì)算溢出了;玩家充值的元寶變?yōu)榱?;這個(gè)可是一件大事,畢竟誰(shuí)都擔(dān)不起這個(gè)責(zé)任啊;
來(lái)說(shuō)說(shuō)原因吧。開(kāi)發(fā)語(yǔ)言是 java 工具是 netbeans ide 8.0.2
玩家對(duì)象有一個(gè)屬性是 gold 是int類型的;
玩家充值的時(shí)候計(jì)算方式如下.
int gold = 20000;//玩家原有的 int tempGold = 20000;//玩家現(xiàn)在充值的 if (Integer.MAX_VALUE >= gold + tempGold) { gold = gold + tempGold; } else { gold = Integer.MAX_VALUE; }看上去好像沒(méi)什么問(wèn)題是吧。當(dāng)然以上是模擬的;
如果你經(jīng)驗(yàn)豐富的話,或以下看出一些端倪,那就是會(huì)溢算的;
也許可能你看不出什么問(wèn)題,我剛開(kāi)始也沒(méi)發(fā)現(xiàn)什么問(wèn)題,所以代碼就這么寫了,那好,我們來(lái)模擬一下
int gold = Integer.MAX_VALUE - 1800;//玩家原有的 int tempGold = 20000;//玩家現(xiàn)在充值的 if (Integer.MAX_VALUE >= gold + tempGold) { gold = gold + tempGold; System.out.好大家猜一猜,這是會(huì)輸出什么結(jié)果????
也許你會(huì)回答輸出 2 對(duì)。沒(méi)錯(cuò)我也以為會(huì)輸出 2 ,

可是運(yùn)行結(jié)果為什么是 1 呢?
首先我們分析一下,為什么我們以為會(huì)輸出 2 ?那么很明顯我們把
gold + tempGold
這兩個(gè)值的計(jì)算想當(dāng)然的以為會(huì)變成 long 型 而大于Integer.MAX_VALUE
然而事實(shí)并非這樣,我來(lái)看看輸出結(jié)果
int gold = Integer.MAX_VALUE - 1800;//玩家原有的 int tempGold = 20000;//玩家現(xiàn)在充值的 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的機(jī)制下gold +tempGold 相加并非變成 long 型而是負(fù)數(shù)
看到這里,也許你會(huì)嘲笑我,好吧我承認(rèn),我確實(shí)沒(méi)有驗(yàn)證過(guò)這個(gè)問(wèn)題。好在游戲還沒(méi)有上線。測(cè)試發(fā)現(xiàn)問(wèn)題。
不管這樣,現(xiàn)在我發(fā)現(xiàn)了這個(gè)問(wèn)題,并且了解到了問(wèn)題所在。好吧想辦法解決唄。
也就是把 int 轉(zhuǎn)變?yōu)?long 的問(wèn)題
int gold = Integer.MAX_VALUE - 1800;//玩家原有的 int tempGold = 20000;//玩家現(xiàn)在充值的 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);測(cè)試一下現(xiàn)在的輸出結(jié)果呢?
--- exec-maven-plugin:1.2.1:exec (default-cli) @ game-gamesr ---2-2147463649------------------------------------------------------------------------BUILD SUCCESS
這些正確了,,好吧。。犯二的事情結(jié)束了。可是發(fā)現(xiàn)這里多了一個(gè)變量 longtempLGold;屬性和操作不是很方便,還有沒(méi)有更好的操作;
int gold = Integer.MAX_VALUE - 1800;//玩家原有的 int tempGold = 20000;//玩家現(xiàn)在充值的 if (Integer.MAX_VALUE >= gold + tempGold + 0L) { gold = gold + tempGold; System.out.println("1"); } else { gold = Integer.MAX_VALUE; System.out.println("2"); }注意后面那個(gè)0L
看看輸出
--- exec-maven-plugin:1.2.1:exec (default-cli) @ game-gamesr ---1------------------------------------------------------------------------BUILD SUCCESS
結(jié)果還是輸出1,也許你會(huì)嘲笑我有范二了,對(duì)我確實(shí)犯二 了,,深究才知道 運(yùn)算符優(yōu)先級(jí)問(wèn)題。
那好吧再改改
int gold = Integer.MAX_VALUE - 1800;//玩家原有的 int tempGold = 20000;//玩家現(xiàn)在充值的 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;//玩家現(xiàn)在充值的 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
這下正確的了,,,
失足程序員的犯二事情啊。。。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注