第461章 還有高手?


 
  顧凡繼續解釋道:“那麼計算機具體是怎麼儲存小數的呢?

  “這就是我之前所說的‘浮點數’,浮點的意思是,小數點是可以浮動的。

  “就比如1000.101這個二進制數,就可以表示為1.000101 x 23,這有點類似於數學上的科學計數法。

  “在程序中,為了讓二進制用到科學計數法,並且規範化,就要保證小數點左側只有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帶小數的情況,才會觸發。可是為什麼到了遊戲裡,人人都能觸發了!!”

  顧凡輕咳兩聲:“這個……我看一下。”

  他還是打開了《謊言之血》的程序,仔細查看了『狂信者』的相關代碼。

  “莉總,這是因為狂信者這個怪物投技的特殊設定。

  “這個投技,是需要玩家手動掙脫的。按照動態難度的設定,越慢掙脫的玩家就越菜,因此動態難度會隨著投技時間的增長而增長,這很合理吧?”