篇文章主要介紹了Python浮點型(float)運算結果不正確的解決方案,幫助大家更好的利用python進行運算處理,感興趣的朋友可以了解下
一、問題說明
以前對浮點數運行沒有沒有太在意,昨天同事要求把百分比結果保存到檔案上,然后就以保存1位小數的形式給他保存了,
但是今天同事運行時問能不能統一以一位小數的形式保存,當時覺得很奇怪昨天就是以一位小數形式存的怎么還會提這種要求呢,
其給回的截圖確實是部分是一位小數的,但一部分是很長的,查看代碼都統一如下格式:
# 使用round保留三位小數,然后乘以100,最后格式化為帶百分號的字串 rate=f"{round(x/y,3) * 100}%"
代碼上沒看出什么問題,直接運行確實是有些結果是一長串的,進行除錯發現當x為37y為76時即會出現問題,如下圖所示:

進行步驟拆分,發現round方法沒有問題,問題在浮點數乘以100上(同時如下圖可以看到也不是所有浮點數乘都有問題)

二、原因探究
二進制對很多浮點數無法準確表示只能用一個近似值代替,而當使用這些以近似值代替的浮點數進行進算時本質上是這些進似值參與了運算,出來的結果也就是進似值運算后的結果,
也就是說,一是這不是乘100的問題也不是乘法的問題而是整個浮點數運算都有問題,二是這不是python的問題是計算機浮點數存盤的問題像C、Java等其他計算機語言進行運算都會有問題,
如果有朋友沒弄明白的話,可以進我的python學習交流.扣扣.裙巴衣久二五寺久寺二(數字的諧音轉換下可以找到了)一起討論,裙里還可以免費下載Python最新的學習資料和專案實戰案例教程,

可能有人會疑惑:為什么二進制可以表示2不能表示0.2呢?
這是因為數值和字串是不一樣的,如果是字串那么表示2.2點的左右兩邊的2編碼是一樣的就可以了(如ASCII碼:504650),但數值不是這樣,數值的整數部分和小數部分需要一個統一的表示形式,那就是加權位計數法,
整數部分都要以2的0次方(20)到2的無窮次方(2∞)表示,這沒有問題,只要長度足夠就能表示出所有奇數和偶數,2 = 1 * 21 + 0 * 20 = 10
小數部分都要以2的-1次方(2-1)到2的負無窮次方(2-∞)表示,這就有問題,因為比如2-1...2-∞不管怎么組合都不能完全等于0.2,0.2 = 0 * 2-1 + 0 * 2-2 + 1 * 2-3 ...
三、處理辦法
這情況讓我想起上份作業局方領導的一句話,應該是“可以理解但不能接受”,
原理上二進制無法精確表示一些浮點數可以理解,但是就這么回傳個顯然錯誤的結果給用戶那是無法接受的,
python提供了Decimal()方法讓浮點運算結果可以和人平時運算的結果一樣,(Decimal本質應該還是通過加長長度提高精度)

# Decimal傳字串才能準確表示,所以需要先用str()把round()的結果轉為字串 rate=f"{Decimal(str(round(x/y,3))) * 100}%" # 其實上邊的結果出來是48.700%的形式,即三位小數的形式并不太符合我們保留一位小數的想法,真正符合想法得下面這樣 # rate=f"{round(Decimal(str(round(x/y,3))) * 100, 1)}%" # 其實我們說了這么多,我們都是建立在決定保留多少位再乘100這個前提下,倘若我們先乘100后決定保留幾位那都不需要用Decimal # rate=f"{round(x/y*100,1)}%"

參考:
https://www.programiz.com/python-programming/numbers
https://docs.python.org/3.7/library/decimal.html
以上就是Python浮點型(float)運算結果不正確的解決方案的詳細內容,更多關于Python浮點型(float)運算結果不正確的資料可以進我的Python學習交流.扣扣.群:巴衣久二五寺久寺二(數字的諧音轉換下可以找到了)下載,還有2020年秋季python最新學習資料、專案實戰案例教程和BAT面試題可以免費下載
本文的文字及圖片來源于網路加上自己的想法,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/125479.html
標籤:其他
