作者descent (「雄辯是銀,沉默是金」)
看板Soft_Job
標題Re: [討論] 請大家聊聊 JavaScript的缺陷
時間Thu Jan 15 21:30:57 2026
對這問題很好奇, 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 << "--- 模擬底層數值轉換 ---" << std::endl;
39
40 // 看看 0.005 實際上在想什麼
41 my_print_fixed(n1, 2);
42
43 // 看看 0.015 實際上在想什麼
44 my_print_fixed(n2, 2);
45
46 n2 = 0.025;
47 my_print_fixed(n2, 2);
48 n2 = 0.035;
49 my_print_fixed(n2, 2);
50 n2 = 0.045;
51 my_print_fixed(n2, 2);
52 n2 = 0.055;
53 my_print_fixed(n2, 2);
54 n2 = 0.065;
55 my_print_fixed(n2, 2);
56 n2 = 0.075;
57 my_print_fixed(n2, 2);
58 n2 = 0.085;
59 my_print_fixed(n2, 2);
60 n2 = 0.095;
61 my_print_fixed(n2, 2);
62 return 0;
63 }
list 5 fn.cpp 執行結果
1 --- 模擬底層數值轉換 ---
2 0.00500000000000000010
3 Input: 0.00500000000000000010 | Result: 0.01
4 0.01499999999999999944
5 Input: 0.01499999999999999944 | Result: 0.01
6 0.02500000000000000139
7 Input: 0.02500000000000000139 | Result: 0.03
8 0.03500000000000000333
9 Input: 0.03500000000000000333 | Result: 0.04
10 0.04499999999999999833
11 Input: 0.04499999999999999833 | Result: 0.04
12 0.05500000000000000028
13 Input: 0.05500000000000000028 | Result: 0.06
14 0.06500000000000000222
15 Input: 0.06500000000000000222 | Result: 0.07
16 0.07499999999999999722
17 Input: 0.07499999999999999722 | Result: 0.07
18 0.08500000000000000611
19 Input: 0.08500000000000000611 | Result: 0.09
20 0.09500000000000000111
21 Input: 0.09500000000000000111 | Result: 0.10
另外注意 fn.cpp L19, 需要用 long double, 如果用 double 結果 0.015 印出來會
是 0.02, 因為演算法 L23 value * multiplier 0.014999999999999999 X 100
變成是 1.50000000000000000000, 而不是 1.4999,
需要使用精度更高的 long double 才會是 1.4999。
※ 引述《accessdenied (存取違規)》之銘言:
: https://i.imgur.com/inyE92c.jpg
: 有誰可以告訴我,JavaScript 的 toFixed()為什麼遇到1,4,7這幾個數字後面的5不會
: 進位呢?
--
紙上得來終覺淺,絕知此事要躬行。
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 101.8.139.147 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/Soft_Job/M.1768483879.A.369.html
1F:噓 MoonCode: 01/15 22:37
2F:噓 nh60211as: 蛤 01/15 23:55
3F:推 galaxy4552: 哇 聽不懂 如果說這個問題在leetcode 難度會在哪 01/16 00:46
4F:推 NDark: 這年頭還有人回娘家 01/16 01:31
5F:→ jonathan793: 讚 留言 分享 01/16 05:07
6F:推 jobintan: 有人挖舊文炒熱總比沒有好,要不然,這板上的草都要長 01/16 07:41
7F:→ jobintan: 得比人高了。 01/16 07:41
8F:推 bradyhau106: 蠻有趣的討論 至少不是AI正邪大戰 01/16 08:23
9F:推 stupid0319: 我以為浮點數運算是看CPU決定的 01/16 08:28
10F:推 sw12: 太強!翻到四五年前的文章在回應,還是專業討論。 01/16 09:25
也不是, 202011 月看到這篇文章時, 我就很好奇怎麼得到這樣的結果,
嘗試研究搜尋後, 找出來的演算法全都不是這樣的結果,
cfront cout fixed 我還特別去看, 但 cfront cout fixed 並不是這樣的結果。
最近剛好又回憶到這問題, 才想藉由 ai 來試試看。
11F:推 Romulus: 蝦還有這種事?真的第一次聽到靠近偶數這回事 01/16 13:57
12F:推 nashmvp: 推 01/16 20:28
13F:推 gmoz: 浮點數精準度不是老梗嗎 IEEE754 01/16 23:24
14F:→ gmoz: 每家取整實作都不太一樣要查一下 不一定都是四捨六入五成雙 01/16 23:25
15F:→ gmoz: 像python2 vs 3 01/16 23:25
16F:→ gmoz: 問ai應該要多問他 其他語言或不同版本是不是一樣實作吧 01/16 23:26
17F:→ gmoz: 單一問題不延伸確認 很常會被AI虎的一知半解 01/16 23:26
※ 編輯: descent (101.8.225.152 臺灣), 01/17/2026 14:35:56