不要使用 Python3 內建的 round()

今天是確診在家荒廢第六天,想說一直這樣廢下去也不太好,就打開了 Leetcode 看看,看了一題 medium 的題目,好難啊一時想不到,回到列表。又上下看了下,有一題 hard 的,聽說 hard 都不是我們這種敲鍵盤的猴子可以進去的,就決定進去看一下是什麼東西。

怎麼好像比想像中的親民?

既然好像不算太難,就開始動手解吧。

然後正當我再找四捨五入的時候,找到兩種四捨五入的方式:

  1. 內建的 round()
  2. math 套件

通常寫 leetcode 的時候,我個人比較不喜歡引入非內建的函式,這樣才有挑戰的感覺?因此我不是選擇第二種,而是使用內建的round()

但我查到的資料上說,這個方式會有精度誤差,不過我在互動式介面上測試好像沒有啊?看來我的電腦比較聰明,那就照用吧XD這一用下去不得了了,leetcode 給了我大大的「wrong answer」。

當然接著就是開始的 debug 時間,一行一行 print 出來後發現,居然是 round() 這行給出了不正確的數字,可是我之前有測試一些 test case 都是正確的啊?就使用了出錯的 case 跑一次……還真的是錯的。重新召喚出互動式介面開始測試,結果發現有趣的事情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
E:\code>py
Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> round(1.5)
2
>>> round(2.5)
2
>>> round(3.5)
4
>>> round(4.5)
4
>>> round(5.5)
6
>>> round(5.1)
5
>>>

欸不是,你怎麼 1.5 和 2.5 四捨五入後都變成 2 啊!3.5 和 4.5 也有相同問題,就算回頭使用我剛剛提到的資料上說的,印出 50 位數也看不出問題。

不過不管怎麼說,既然知道有問題,那就是要避免使用。於是最後直接改用強制整數的方式達成無條件捨去再自己 +1。這樣就能達成不用另外 import 函式庫也能解題了:

比使用 statistics.median() 成績還要好?

跑出來的數字居然比使用 statistics.median() 成績還要好,真是天才(X)

總之經過這次踩坑,特別把他筆記起來,以後記住:

不要使用 round() 來進行四捨五入計算!