100 元三個人平分。算到元,每人 33 元,加起來 99——少了一塊; 算到分,每人 33.33 元,加起來 99.99——少了一分。 不管切到哪一位,除不盡的那一點都得有人拿。
這聽起來像小學數學的無聊問題,但分帳有一個不能違反的性質:分出去的金額加總,必須剛好等於原金額。 少了代表有人白付,多了代表憑空生錢,而且誤差會累積—— 一趟旅行三十筆費用,就是三十次機會。下面以「元」為單位說明, 小數位更多的幣別道理完全一樣。
四種處理方式,只有前三種可用
| 做法 | 100 元三人的結果 | 特性 |
|---|---|---|
| 餘數固定給第一位 | 34 / 33 / 33 | 結果穩定、可預測、隨時重算都一樣 |
| 餘數輪流承擔 | 34 / 33 / 33 → 下一筆換人 | 長期最公平,但要記住上次輪到誰 |
| 付款人吸收 | 33 / 33 / 33,付款人自己多 1 | 對付款人不利,但最不需要解釋 |
| 各自進位到元 | 34 / 34 / 34 = 102 | 總和超過原金額,不可用 |
第四種是最直覺、也最常見的錯誤:讓每個人各自處理自己的小數。 向上進位變成 34 / 34 / 34 = 102,多出兩塊;四捨五入變成 33 / 33 / 33 = 99,少了一塊。 兩種都對不起來,而且多出或少掉的錢在帳面上不存在, 你花半小時也找不出是哪一筆造成的。
正確的做法都有同一個特徵:先算出每個人的整數部分, 剩下的餘數指定給某個特定的人,而不是讓每個人各自處理小數。 100 ÷ 3 = 33 餘 1,那 1 元指定給誰都可以,但一定要有人拿。
為什麼「固定給第一位」通常是最好的選擇
輪流承擔聽起來更公平,但它引入了狀態:系統必須記住上一次輪到誰。 這會產生一個很麻煩的副作用——重算的結果會跟原本不一樣。 你改了某一筆費用的金額,整本帳重算,輪替的順序就跑掉了, 於是三個月前那筆帳的分攤金額莫名其妙變了。
固定給第一位(通常是分攤名單的第一個人)沒有這個問題: 同樣的輸入永遠得到同樣的輸出。而且實務上,一塊錢的偏差在多筆費用之間會自然抵銷—— 分攤名單的順序會隨著參與的人變動,不會總是同一個人吃虧。
真正需要在意的是規則的一致性,不是那一塊錢。 沒有人會因為少收一塊錢生氣;但很多人會因為「上次跟這次算法不一樣」而不信任這本帳。
浮點數:那個歸不了零的 0.0000001
如果分帳工具直接用小數運算,會遇到第二個問題。電腦用二進位表示小數, 而 0.1 在二進位裡是無限循環,只能取近似值。所以:
0.1 + 0.2不等於0.3
這不是 bug,是浮點數的定義。實際影響是:三十筆費用累加下來, 某個人的淨額算出來是 0.00000000000004 而不是 0。 於是結算頁會多出一筆「A 應轉 0 元給 B」的轉帳—— 金額顯示成 0,但它就在那裡,看起來像系統壞了。
兩種標準解法:
- 用最小單位的整數運算。把所有金額換算成「分」(或該幣別的最小單位)用整數算,最後才除回來。 完全沒有誤差,是金融系統的標準做法。
- 用容差判斷歸零。保留小數,但判斷「這個淨額算不算零」時用一個門檻, 例如絕對值小於 0.005 元就當成零。實作簡單, 對分帳這種金額量級來說完全足夠。
ShareMoney 用的是第二種,門檻 0.005 元——半分錢。 任何小於半分錢的餘額都不會產生轉帳。細節寫在結算原理。
幣別的小數位不一樣,這會咬人
| 幣別 | 小數位 | 最小單位 |
|---|---|---|
| 日圓 JPY | 0 | 1 圓 |
| 韓元 KRW | 0 | 1 元 |
| 越南盾 VND | 0 | 1 盾 |
| 台幣 TWD | 2 | 帳目 0.01 元/現金 1 元 |
| 美元 USD | 2 | 0.01 元 |
| 歐元 EUR | 2 | 0.01 元 |
日圓、韓元、越南盾沒有小數位,所以 10,000 日圓三個人分是 3,334 / 3,333 / 3,333,餘數是 1 日圓(約 0.22 台幣)。 美元有兩位,所以 100 美元三人分是 33.34 / 33.33 / 33.33,餘數是 1 美分。
台幣是個混合的例子:帳目上保留到分(所以才需要前面說的容差判斷), 但實際轉帳只到元。5,000 元三個人分,帳上是 1,666.67,轉帳時就轉 1,667, 多的三角當作請對方喝飲料——這比為了三角錢對帳合理得多。
混幣別的帳本要小心一件事:在哪一步四捨五入。 如果先把日圓分給三個人、再各自換算成台幣, 每個人的台幣金額都會帶一個換算後的小數,加起來不等於原費用的台幣金額。 正確的順序是先換算成結算幣別,再分攤—— 一筆費用只換算一次,分攤在結算幣別上完成。
這也是為什麼結算要以單一幣別為基準。外幣是輸入與顯示的方便, 淨額只有一套。更多外幣的實務問題在海外刷卡的匯率。
實務上該堅持與不該堅持的
- 該堅持:總和守恆。分攤加總 = 費用金額,所有人的淨額加總 = 0。 這兩個等式是檢查有沒有算錯最快的方法,任何時候不成立就是有問題。
- 該堅持:規則一致。同一本帳從頭到尾用同一套尾數規則,重算的結果要跟上次一樣。
- 不該堅持:追那一塊錢。花二十分鐘討論餘數該給誰,成本遠高於那一塊錢; 轉帳時把小數進位到整數元也一樣——規則講一次、之後照著跑就好。