藍橋杯輔導視頻學習-浮點數的注意事項

浮點數不能精確比較
藍橋杯例題1:
這裏寫圖片描述
浮點數:對它的說法是足夠接近 |a - b| < seta,而不是完全相等(不能用 == 來判斷,這是大忌)。因爲計算式內部是採用二進制的方式來表示。

上題可以用暴力破解法,

for (int a = 0; a < 100 ; a++)  //a 是啤酒數量,b是飲料的數量,假設它們的取值範圍都在0 ~ 100
{
    for (int b = 0; b < 100; b++)
    {
           if (a * 2.3  + b * 1.9 == 82.3)    printf("%d , %d \n",a,b);
    }
}

但關於浮點運算,用以上的暴力破解法存在隱患,可用以下方法進行改善 (避開浮點數)。
避開浮點數:價錢都是以元爲單位,存在小數,那麼全都乘10倍,改成以角爲單位。

for (int a = 0; a < 100 ; a++)  
{
    for (int b = 0; b < 100; b++)
    {
           if (a * 23  + b * 19 == 823)    printf("%d , %d \n",a,b);
    }
}//雖然與前一種方法沒什麼差別,但避開浮點數,可以有效的避開題目中或許隱含着的陷阱。

藍橋杯例題2:
這裏寫圖片描述
這裏寫圖片描述

【注意】
寫成16行那樣是錯誤的:因爲1/XXX得到的答案都0
寫成17行那樣可行,可是對於浮點運算用了 == 進行比較,雖然能得出正確結論,但存在隱患
解決存在的隱患:
1). 寫成17行那樣,但進行比較時不用==,而是用 abs (1.0/a + 1.0/b + 1.0/c + 1.0/d - 1.0) < 1E-10(或其他小數)進行比較。
2).寫成18行那樣,用通分的方法,解決存在分母的問題,等式兩邊同乘上 abcd(要注意是否超過整型範圍)。

浮點數:一般我們表示的都是有理數。 有理數的表示:分子/分母。

浮點數運算時目前採用的規則是IEEE754,該規則規定浮點數有幾個特殊的值:(double類型)

  • Infinity 無窮大 ,如double a = 3.0 / 0 可得到的值
  • 減號 Infinity 負無窮大
  • 0.0 ,如 1/a 可取得
  • 減號 0.0,如1/(-a) NAN:Not a Number ,無意義,如a/a,a-a 都可得到

如例題:要求有效數字100位,即任意精度的小數。

浮點數的四捨五入模式:四捨六入五成雙。
比如有浮點數3.150,捨去則是3.1,加入則是3.2,所以最後的結果是3.2,成雙。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章