python的数字比较好_说说 Python3 中的数字处理
最近在處理訂單相關的問題,踩了數字的一些坑,在此記錄下。
其中有問題的代碼涉及金額比較,便于描述,假設了下面一段代碼
def is_paid(pay_price, paid_price):
return pay_price == paid_price
# 數據表中的記錄類似這樣
# id pay_price ...
# 1 12.3
# ...
# 操作如下
# 這里使用了 SQLAlchemy 的 ORM 形式讀取數據
order = Order.query.filter_by(id=1).first()
if is_paid(order.pay_price, 12.3):
print('paid')
else:
print('unpaid')
# 最后打印的卻是 unpaid
跟蹤代碼才發現 order.pay_price 是 Decimal 類型,而 12.3 是浮點類型,Python 是強類型語言,類型不一樣當然不等。
>>> from decimal import Decimal as d
>>> a = d('12.3')
>>> b = 12.3
>>> type(a)
>>> type(b)
>>> a
Decimal('12.3')
>>> b
12.3
>>> a == b
False
仔細想想,有點不對,你看 1 == 1.0 就成立啊,不也是不同類型(整型和浮點型)嗎。
不管是不是強類型語言,數字之間作比較還是應該要能行的吧。
這里沒有深挖,感覺就是 Python 設計的緣故吧。
所以,這里應該怎么作等值比較,試了下 math.isclose(a, b) ,嗯,行得通。
本應該在這里結束了,但,不小心玩了下
>>> m = 0.1 + 0.2
>>> n = 0.3
>>> m == n
False
納尼
然后打印了下值
>>> m
0.30000000000000004
>>> n
0.3
我還有什么話可說呢,這下讓我對 Python 浮點數的處理產生了懷疑。
也讓自己對以前所寫的數字比較產生了懷疑,天哪,全是 Bug 。不過后面想通了,不存在的 :)
>>> x = 1.0
>>> y = Decimal('2')
>>> x + y
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'float' and 'decimal.Decimal'
這下,搞得我以后都不知道怎么處理數字了。程序中很多地方都沒判斷類型,呀,又是一堆隱患。(同樣,還是想多了...)
為了理清自己的思路,又試了下
>>> z = 3
>>> y + 3
Decimal('5')
原來,Decimal 和整型是能進行算術運算的。
后面自己冷靜了下,終于想通了。
程序中,我們用的很多庫,涉及小數的基本上都是用的 Decimal 類型,比如 SQLAchemy ORM 取出來的小數數據都是此類型。
Decimal 之間比較一般精度的數字都是沒問題的,并且程序中我們定義數字的初始值基本都是整型 0 ,和 Deciamal 運算沒有問題,所以上面的疑慮都煙消云散了。
所以,在以后的數字處理中,自己盡量只使用整型和 Decimal 類型,來避免上面的隱形問題。
不過,要注意
>>> t1 = Decimal(0.123)
>>> t2 = Deciaml('0.123')
>>> t1 == t2
False
這是由于浮點數 0.123 在轉為 Decimal 的時候失去了精度
>>> t1
Decimal('0.1229999999999999982236431605997495353221893310546875')
>>> t2
Decimal('0.123')
因此,定義 Decimal 類型的時候,我們盡量使用字符串來避免這個問題。
本文首發于公眾號「小小后端」,關注并回復「1024」有驚喜哦。
總結
以上是生活随笔為你收集整理的python的数字比较好_说说 Python3 中的数字处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue双击事件_我总结了12个Vue.j
- 下一篇: floatingactionbutton