作者:
descent (「雄辯是銀,沉默是金」)
2026-01-15 21:30:57對這問題很好奇, c++ 也有類似的情形。
1 #include <iostream>
2 #include <string>
3 #include <cmath>
4 using namespace std;
5
6 int main(int argc, char *argv[])
7 {
8 std::cout.precision(2);
9 cout << fixed << 0.005 << endl;
10 cout << 0.015 << endl;
11 cout << 0.025 << endl;
12 cout << 0.035 << endl;
13 cout << 0.045 << endl;
14 cout << 0.055 << endl;
15 cout << 0.065 << endl;
16 cout << 0.075 << endl;
17 cout << 0.085 << endl;
18 cout << 0.095 << endl;
19 return 0;
20 }
n.cpp 執行結果
0.01
0.01
0.03
0.04
0.04
0.06
0.07
0.07
0.09
0.10
藉由 ai, 終於知道是怎麼回事, 當決定要印出小數點 2 位數時候用的演算法是
「偶數捨入法」(Banker's Rounding) 這是很多繪圖、統計或會計系統的規則:
若剛好在 .5 的位置, 則捨入到最接近的「偶數」。
0.005 → 靠近 0.00 還是 0.01? 這裡 0 是偶數, 所以會趨向 0.00, 但在電腦裡
0.005 是 0.00500000000000000010 所以它判斷靠近 0.01。
0.015 → 靠近 0.01 還是 0.02? 這裡 2 是偶數, 本應往 0.02 走, 但在電腦裡 0.015
是 0.0149..., 所以它決定留在 0.01。
另外也請 ai 給出一個簡易版本的演算法, 實作 Banker's Rounding。
fn.cpp
1 #include <iostream>
2 #include <iomanip> // 必須包含此庫以使用 setprecision
3
4 #include <cmath>
5 #include <string>
6 #include <cstdio>
7
8 using namespace std;
9
10 /**
11 * 模擬 setprecision(2) + fixed 的行為
12 * @param value 要輸出的數值
13 * @param precision 小數點後位數
14 */
15 void my_print_fixed(double value, int precision) {
16 cout << fixed << setprecision(20) << value << endl;
17
18 // 1. 取得放大倍數 (例如 precision 2 則為 100)
19 long double multiplier = std::pow(10, precision);
20
21 // 2. 模擬底層捨入規則
22 // 注意:std::round 在這裡會反映出 0.015 儲存成 0.01499... 的事實
23 double rounded_value = std::round(value * multiplier) / multiplier;
24
25 // 3. 格式化輸出字串
26 // 我們用 printf 的格式化字串來模擬輸出流的最後一步
27 char format[10];
28 sprintf(format, "%%.%df", precision);
29 printf("Input: %.20f | Result: ", value);
30 printf(format, rounded_value);
31 printf("\n");
32 }
33
34 int main() {
35 double n1 = 0.005;
36 double n2 = 0.015;
37
38 std::cout << "