电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

聊聊Python中的浮點數運算不準確問題

瀏覽:88日期:2022-06-24 17:03:25

大家好,老 Amy 來了。之前就意識到一個問題,但是最近又有朋友提出來了,所以就想著干脆記錄下來,分享給大家叭~

啥問題呢?請看題:

聊聊Python中的浮點數運算不準確問題

也就是說,需要大家計算1.1-1的值,很多朋友會說:“emmm…這還不簡單,玩我呢?不就是0.1嘛”

但是如果你用 python 去執行一下,會發現結果跟你想的不太一樣,如下圖:

聊聊Python中的浮點數運算不準確問題

這樣大家是不是發現了什么問題?是的,浮點數在運算過程中并沒有保證完全精確,是什么原因導致了這種現象呢?很多朋友就會竊喜:“這不就是 Python 的 bug 嘛~”

但實際上,這并不是 Python 中的 bug ,它和計算機硬件中如何處理浮點數有關。浮點數在計算機硬件中以二進制的形式存在,但是我們現在看到的都是十進制,而十進制的浮點數不能都完全精確的表示為二進制小數。

就比如說我們在十進制數中無法用小數精確表示 1/3 一樣,在二進制數中也無法用小數精確表示 1/10。顯然這樣子的說明并沒有十進制中的 1/3 那么直觀,接下來我們嘗試去計算一下二進制中的 1/10 :

十進制的整數位是二進制的整數位,十進制的小數位是二進制數的小數位。那現在我們拿到0.1

整數部分為0

小數部分為0.1,并順序取值

0.1*2=0.2<1取00.2*2=0.4<1取00.4*2=0.8<1取00.8*2=1.6>1取10.6*2=1.2>1取10.2*2=0.4<1取0…

有沒有發現?在二進制下,1/10 是一個無限循環小數:0.00011001100110011…,顯然這樣的表示形式無法精確的表示浮點數,最終的結果是近似 1/10 。在使用 IEEE-754 浮點運算標準的計算機硬件上,Python 的浮點數映射為 IEEE-754 雙精度浮點數,共包含 53 位精度(這里指的是二進制),在這個范圍下,這個最接近 1/10 的結果是:

3602879701896397/2∗∗55

這表示在計算機硬件中,1/10 的真實十進制數值為:

0.1000000000000000055511151231257827021181583404541015625

那如何進行精確的浮點數運算呢?有朋友提出四舍五入可以解決。那我們來仔細看一下四舍五入真的可以解決這個問題嗎?

四舍五入進行解決

在 python 中,使用 round(number[, ndigits]) 來進行四舍五入,其中 ndigits 表示保留幾位小數,默認為0。

我們來看代碼如下:

In [10]: round(0.6)Out[10]: 1In [11]: round(0.65,1)Out[11]: 0.7In [12]: round(0.64,1)Out[12]: 0.6

上面代碼符合我們四舍五入的預期結果,但是不要著急,我們接著往下看:

In [13]: round(1.15,1)Out[13]: 1.1In [14]: round(0.5)Out[14]: 0In [15]: round(1.5)Out[15]: 2

這樣看是不是有些問題,什么問題呢?按照四舍五入的話,round(1.15)會直接進為1.2,但是此時并沒有,而是變為了1.1。這是為什么呢?

如果沒有上面對浮點數的了解,僅從表象上很難去解釋。我們已經知道了在計算機內部,對于一些浮點數是無法精確表示的,比如上面代碼中 1.15,我們可以通過 format() 來看看它在計算機內部更加具體的數值:

In [16]: format(1.15,'.51f')Out[16]: ’1.149999999999999911182158029987476766109466552734375’

看到這個結果,我們就恍然大悟,為什么看到的結果會是1.1了。

但是接下來,可能會更加的困惑,因為對于 0.5 來說,是完全可以直接轉為二進制表示的。但是round(0.5)結果卻為0?這是因為 round() 的工作原理為:對于 round(number[, ndigits]),如果 number 可以被正常處理,則它的值會被舍入到最接近的 10 的負 ndigits 次冪的倍數上,對于與兩個倍數的差值(差值的絕對值)均相等的情況,則會選擇兩個倍數中的偶數。

# 最接近的10的負0次冪的倍數為0、1,并與0、1差值的絕對值相同,選擇偶數0>>> round(0.5) 0# 最接近的10的負2次冪的倍數為0.12、0.13,并與0.12、0.13的差值的絕對值相同,選擇偶數0.12>>> round(0.125, 2) 0.12# 最接近的10的負2次冪的倍數為0.13>>> round(0.12548828125, 2) 0.13

這個規則,用我們熟悉的話來說即為“ 四舍六入五成雙 ”。

使用decimal進行浮點數的精確計算

那我們在 Python 中怎么進行精確的浮點數計算呢,Python 標準庫為我們提供了decimal 這個模塊來解決這個問題,decimal 常用于需要精確處理浮點數的場合,比如銀行賬戶金額、貨幣加減等。

In [17]: from decimal import DecimalIn [18]: 0.1-0.09Out[18]: 0.010000000000000009In [19]: Decimal(’0.1’)-Decimal(’0.09’)Out[19]: Decimal(’0.01’)

同樣,我們可以使用它來查看對于不能精確表示的浮點數在計算機內部的具體數值:

In [20]: Decimal.from_float(1.1)Out[20]: Decimal(’1.100000000000000088817841970012523233890533447265625’)In [21]: Decimal.from_float(0.1)Out[21]: Decimal(’0.1000000000000000055511151231257827021181583404541015625’)

這樣就可以解決我們的困惑與問題啦~

補充:python做浮點數運算時的坑記錄

聊聊Python中的浮點數運算不準確問題

聊聊Python中的浮點數運算不準確問題

很顯然,這個計算結果是不對的,而且偏離實際值十分遠。。。。。。。。

太坑人了這。

本來想自動截取計算得到的圖片尺寸,但是這計算結果,坑害了半天的查找錯誤過程!!!!

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持好吧啦網。如有錯誤或未考慮完全的地方,望不吝賜教。

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 超声骨密度仪-动脉硬化检测仪器-人体成分分析仪厂家/品牌/价格_南京科力悦 | 世纪豪门官网 世纪豪门集成吊顶加盟电话 世纪豪门售后电话 | 烟台条码打印机_烟台条码扫描器_烟台碳带_烟台数据采集终端_烟台斑马打印机-金鹏电子-金鹏电子 | 淄博不锈钢无缝管,淄博不锈钢管-鑫门物资有限公司 | 舞台木地板厂家_体育运动木地板_室内篮球馆木地板_实木运动地板厂家_欧氏篮球地板推荐 | 定制异形重型钢格栅板/钢格板_定做踏步板/排水沟盖板_钢格栅板批发厂家-河北圣墨金属制品有限公司 | MTK核心板|MTK开发板|MTK模块|4G核心板|4G模块|5G核心板|5G模块|安卓核心板|安卓模块|高通核心板-深圳市新移科技有限公司 | 富森高压水枪-柴油驱动-养殖场高压清洗机-山东龙腾环保科技有限公司 | 美国PARKER齿轮泵,美国PARKER柱塞泵,美国PARKER叶片泵,美国PARKER电磁阀,美国PARKER比例阀-上海维特锐实业发展有限公司二部 | 螺旋丝杆升降机-SWL蜗轮-滚珠丝杆升降机厂家-山东明泰传动机械有限公司 | 贵州成人高考网_贵州成考网 | 量子管通环-自清洗过滤器-全自动反冲洗过滤器-北京罗伦过滤技术集团有限公司 | 智能门锁电机_智能门锁离合器_智能门锁电机厂家-温州劲力智能科技有限公司 | 车件|铜件|车削件|车床加工|五金冲压件-PIN针,精密车件定制专业厂商【东莞品晔】 | 禹城彩钢厂_钢结构板房_彩钢复合板-禹城泰瑞彩钢复合板加工厂 | 预制舱-电力集装箱预制舱-模块化预制舱生产厂家-腾达电器设备 | 细砂提取机,隔膜板框泥浆污泥压滤机,螺旋洗砂机设备,轮式洗砂机械,机制砂,圆锥颚式反击式破碎机,振动筛,滚筒筛,喂料机- 上海重睿环保设备有限公司 | 郑州巴特熔体泵有限公司专业的熔体泵,熔体齿轮泵与换网器生产厂家 | ALC墙板_ALC轻质隔墙板_隔音防火墙板_轻质隔墙材料-湖北博悦佳 | PCB设计,PCB抄板,电路板打样,PCBA加工-深圳市宏力捷电子有限公司 | 沈阳建筑设计公司_加固改造设计_厂房设计_设计资质加盟【金辉设计】 | 档案密集架,移动密集架,手摇式密集架,吉林档案密集架-厂家直销★价格公道★质量保证 | 预制直埋蒸汽保温管-直埋管道-聚氨酯发泡保温管厂家 - 唐山市吉祥保温工贸有限公司 | 球形钽粉_球形钨粉_纳米粉末_难熔金属粉末-广东银纳官网 | 上海噪音治理公司-专业隔音降噪公司-中广通环保 | 厚壁钢管-厚壁无缝钢管-小口径厚壁钢管-大口径厚壁钢管 - 聊城宽达钢管有限公司 | 加热制冷恒温循环器-加热制冷循环油浴-杭州庚雨仪器有限公司 | 压滤机-洗沙泥浆处理-压泥机-山东创新华一环境工程有限公司 | 全自动真空上料机_粉末真空上料机_气动真空上料机-南京奥威环保科技设备有限公司 | lcd条形屏-液晶长条屏-户外广告屏-条形智能显示屏-深圳市条形智能电子有限公司 | 香蕉筛|直线|等厚|弧形|振动筛|香蕉筛厂家-洛阳隆中重工 | 金刚网,金刚网窗纱,不锈钢网,金刚网厂家- 河北萨邦丝网制品有限公司 | 云南标线|昆明划线|道路标线|交通标线-就选云南云路施工公司-云南云路科技有限公司 | 水篦子|雨篦子|镀锌格栅雨水篦子|不锈钢排水篦子|地下车库水箅子—安平县云航丝网制品厂 | 医用酒精_84消毒液_碘伏消毒液等医用消毒液-漓峰消毒官网 | 气动调节阀,电动调节阀,自力式压力调节阀,切断阀「厂家」-浙江利沃夫自控阀门 | 药品/药物稳定性试验考察箱-埃里森仪器设备(上海)有限公司 | 税筹星_灵活用工平台_企业财务顾问_财税法薪综合服务平台 | 首页-浙江橙树网络技术有限公司| 天津云仓-天津仓储物流-天津云仓一件代发-顺东云仓 | 德国EA可编程直流电源_电子负载,中国台湾固纬直流电源_交流电源-苏州展文电子科技有限公司 |