9.7 絕對誤差與相對誤差
浮點數天生帶誤差,上一節已經看得清清楚楚——出題者當然也知道,所以浮點數題目的判定通常長這樣:
「與標準答案的絕對誤差或相對誤差不超過 10^{-6} 即視為正確。」
兩個名詞拆開看(設你的輸出是 v、標準答案是 ans):
- 絕對誤差:兩數相差多少——|v - ans|。例如輸出 1.013、答案 1.02,絕對誤差是 |1.013 - 1.02| = 0.007。
- 相對誤差:差距佔答案本身的比例——\dfrac{|v - ans|}{|ans|}。上例的相對誤差是 0.007 / 1.02 \approx 0.00686。
為什麼要有相對誤差?想像答案是 10^{15} 這麼大——double 總共就 15 \sim 16 位有效數字,「絕對誤差 \le 10^{-6}」根本印不出來;但「相對誤差 \le 10^{-6}」只要求前 6 位有效數字附近是對的,公平多了。題目寫「或」就是兩個條件過一個就算對——大數看相對、小數看絕對,各取所長。
¶你該做的事:把位數印好印滿
看懂要求後,應對方式其實就一句話:用 fixed + setprecision 輸出比要求更多的位數。
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double d;
cin >> d;
cout << fixed << setprecision(12); // 要求 10^-6,就印到 10^-12:綽綽有餘
cout << d * d << '\n';
return 0;
}
執行結果(輸入 1.5):
2.250000000000
反面教材:這題如果用預設輸出,6 位有效數字的四捨五入可能讓誤差達到 10^{-1} 等級(例如答案 123456.7 被印成 123457),誤差要求直接爆掉。凡是誤差判定的題目,第一行先寫 fixed << setprecision(12),再開始想演算法。
動手試試看:題目要求相對誤差 \le 10^{-9},答案的數量級大約是 10^{3}。用 setprecision 印小數點後 12 位夠不夠?印 6 位呢?(動筆算:小數點後 k 位的絕對誤差最多 0.5 \times 10^{-k},除以答案 10^3 就是相對誤差。)