顧凡繼續解釋道:“那麼計算機具體是怎麼儲存小數的呢?
“這就是我之前所說的‘浮點數’,浮點的意思是,小數點是可以浮動的。
“就比如1000.101這個二進製數,就可以表示為1.000101?x?2^3,這有點類似於數學上的科學計數法。
“在程序中,為了讓二進製用到科學計數法,並且規範化,就要保證小數點左側隻有1位,並且必須為1,我們目前絕大多數計算機所使用的浮點數,都是IEEE製定的國際標準,采用符號位+指數位+尾數的格式。
“總之,由於存在十進製到二進製之間的轉化,所以按照這種方式來計算,0.1+0.2並不等於完整的0.3,因為在計算機中,很多小數都無法用完整的二進製來表示,所以隻能用近似數的方式來儲存,那麼兩個近似數相加,也隻能是一個新的近似數。
“十進製轉二進製計算,然後再轉十進製輸出,這就導致了前後兩個數不相等的情況。”
莉莉絲眉頭緊皺:“那為什麼不能用十進製精確計算呢!”
顧凡輕咳兩聲:“這個……如果要從頭解釋『計算機為什麼要使用二進製』的話,就太複雜了,一時半會說不清。
“但針對這個問題,我可以從另一個角度來說明為什麼大家會容忍這種誤差,因為這種誤差本身就是不可消除的。
“即便是十進製,也會出現許多無法除儘的情況。十進製隻是能夠精確表達2和5能夠除儘的數字,但對於1/3、1/7這樣的數字,十進製也就無能為力了,同樣也會產生誤差。
“所以不管采用什麼樣的進製,誤差都是必然存在的。”
莉莉絲感到大腦冒煙:“好吧,我知道了,在計算機裡麵0.1+0.2≠0.3,那麼這個bug又是怎麼回事?”
顧凡長出了一口氣:“莉總你能理解這一點的話,這個bug解釋起來就稍微容易一些了。
“簡單來說就是,程序員在寫動態難度的代碼時,沒有考慮到這種999後麵還帶小數的極端特殊情況,沒有為這種特例專門寫一個判定,因此在數值互相轉化的過程中,程序無法判定這個數字具體處於哪一個難度區間中,就直接降為了最低難度。
“站在人的角度上來看,4999.99當然還是處於5000以內的區間,但對於程序來說卻並不是如此。也就是說,0.1+0.2=0.30000000000000004,它溢出了0.3的正常區間。”
莉莉絲簡直是瞠目結舌,雖然她仍舊無法接受,但從程序的角度來看,這個bug的出現還真就是合情合理。
而且,這並非顧凡信口開河,其他遊戲也出現過類似的bug。
莉莉絲很快又意識到了新的問題:“但假設真的如你所說,這個特例應該很難觸發才對吧?隻有在進入boss房的時候難度數值剛好卡在999帶小數的情況,才會觸發。可是為什麼到了遊戲裡,人人都能觸發了!!”
顧凡輕咳兩聲:“這個……我看一下。”
他還是打開了《謊言之血》的程序,仔細查看了『狂信者』的相關代碼。
“莉總,這是因為狂信者這個怪物投技的特殊設定。
“這個投技,是需要玩家手動掙脫的。按照動態難度的設定,越慢掙脫的玩家就越菜,因此動態難度會隨著投技時間的增長而增長,這很合理吧?”
莉莉絲想了想:“嗯……合理。”
動態難度是《謊言之血》最基礎的設定,簡單來說就是,越菜的玩家難度越高。
那麼從投技的角度來考慮,中了投技的玩家肯定是菜的,中了投技還掙脫很慢的玩家就更菜。因此,投技持續期間持續增長動態難度,這是個非常合理的設計。
顧凡繼續說道:“但是,如果一直持續增加動態難度,似乎也不太合理。
“對於一個投技來說,這種懲罰措施未免太嚴厲了一些。
“所以,為了符合動態難度原本的設計意圖,也為了避免一些莫名其妙的bug,程序上對這個投技的動態難度數值進行了限製,讓它最多隻能增長到當前難度等級下的4999.99,不能增長到下一個難度等級。
“隻有當玩家再被其他怪物打一下的時候,才能突破這個數值,來到下一個動態難度等級。
“這也算是個比較合理的設定。”
莉莉絲微微點頭:“嗯……似乎……”
顧凡繼續說道:“但是這兩個問題疊加在一起的時候,就出現了一個全新的問題。
“那就是當玩家保持著這個數值直接進入boss戰的時候,係統會對當前的動態難度進行一次重新的判定,然後……就沒有然後了。”
莉莉絲不由得目瞪口呆,暫時失去了語言。
從原理上,她已經勉強接受了這個bug。
但是從結果上卻完全無法接受!
因為這個bug的出現,實際上讓玩家打出成神結局的難度大幅降低了!
原本玩家想要把動態難度降到最低,是一個很漫長的過程,不僅要小心翼翼地收集道具、不能被打到,還要儘可能地給怪物造成大量傷害。期間隻要有任何的小失誤,都很有可能前功儘棄。
而被連續打中好幾下導致動態難度漲上去之後,再想要降下來簡直是難如登天。
很多玩家就隻能重開。
在這個過程中,自然就會產生大量的負麵情緒。
可現在呢?玩家根本不需要那麼麻煩,隻需要在進boss房之前找個狂信者抱一下,把動態難度卡成4999.99,再進boss房,動態難度直接就變成最低了!
從網上玩家們對於『狂信者』這個怪物的風評,也能看出這個bug有多麼重大的意義。