色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

浮點運算的尾數部分是如何轉變成二進制的?

lilihe92 ? 來源:最后一個bug ? 2023-07-26 09:30 ? 次閱讀

正文

aff4650a-2aef-11ee-a368-dac502259ad0.png

然后看到這篇關于浮點數的文章,希望大家看了之后有所啟發。

想一下,為什么第一個打印的和預設值不同,但是第二個是相同的?

b02a20d2-2aef-11ee-a368-dac502259ad0.png

b05b70ba-2aef-11ee-a368-dac502259ad0.png

如圖:

尾數部分是如何轉變成二進制的?

b07a8b4e-2aef-11ee-a368-dac502259ad0.jpg

前言

很多人在初學寫程式時都會遇到所謂的浮點誤差,如果你到目前都還沒被浮點誤差雷過,那只能說你真的很幸運XD。

以下圖Python 的例子來說0.1 + 0.2并不等于0.3,8.7 / 10也不等于0.87,而是0.869999…,真的超怪der

b08a106e-2aef-11ee-a368-dac502259ad0.png

但這絕對不是什么神bug,也不是Python 設計得不好,而是浮點數在做運算時必然的結果,所以即便是到了Node.js 或其他語言也都是一樣。

b0a9d37c-2aef-11ee-a368-dac502259ad0.png

電腦如何儲存一個整數(Integer)

在講為什么會有浮點誤差之前,先來談談電腦是怎么用0 跟1 來表示一個整數,大家應該都知道二進制這個東西:像101代表22 + 2? 也就是5、1010代表23 + 21 也就是10。

b0e3d7b6-2aef-11ee-a368-dac502259ad0.png

如果是一個unsigned 的32 bit 整數,代表他有32 個位置可以放0 或1,所以最小值就是0000...0000也就是0,而最大值1111...1111代表231 + 23? + … + 21 + 2? 也就是4294967295。

從排列組合的角度來想,因為每一個bit 都可以是0 或1,整個變數值有232 種可能性,所以可以精確的表達出0 到232-1 中任一個值,不會有任何誤差。

浮點數(Floating Point)

雖然從0 到232-1 之間有很多很多個整數,但數量終究是有限的,就是232 個那么多而已;但浮點數就大大的不同了,大家可以這樣想:在1 到10 這個區間中只有十個整數,但卻有無限多個浮點數,譬如說5.1、5.11、5.111 等等,再怎么數都數不完。

但因為在32 bit 的空間中就只有232 種可能性,為了把所有浮點數都塞在這個32 bit 的空間里面,許多CPU 廠商發明了各種浮點數的表示方式,但若各家CPU 的格式都不一樣也很麻煩,所以最后是以IEEE發布的IEEE 754作為通用的浮點數運算標準,后來的CPU 也都遵循這個標準進行設計。

IEEE 754

IEEE 754 里面定義了很多東西,其中包括單精度(32 bit)、雙精度(64 bit)跟特殊值(無窮大、NaN)的表示方式等。

正規化

以8.5 這個符點數來說,如果要變成IEEE 754 格式的話必須先做正規化:把8.5 拆成8 + 0.5 也就是23 + 1/21,接著寫成二進位變成1000.1,最后再寫成1.0001 x 23,跟十進位的科學記號滿像的。

單精度浮點數

在IEEE 754 中32 bit 浮點數被拆成三個部分,分別是sign、exponent 跟fraction,加起來總共是32 個bit。

b0f28c34-2aef-11ee-a368-dac502259ad0.png

sign:最左側的1 bit 代表正負號,正數的話sign 就為0,反之則是 1。

exponent:中間的8 bit 代表正規化后的次方數,采用的是超127格式,也就是3 還要加上127 = 130。

fraction:最右側的23 bit 放的是小數部分,以1.0001 來說就是去掉1. 之后的000。

所以如果把8.5 表示成32 bit 格式的話就會是這樣:

這圖我畫超久的,請大家仔細看XD。

b10ada5a-2aef-11ee-a368-dac502259ad0.png

什么情況下會不準呢?

剛剛8.5 的例子可以完全表示為23+ 1/21,是因為8 跟0.5 剛好都是2 的次方數,所以完全不需要犧牲任何精準度。

但如果是8.9 的話因為沒辦法換成2 的次方數相加,所以最后會被迫表示成1.0001110011… x 23,而且還會產生大概0.0000003 的誤差,好奇結果的話可以到IEEE-754 Floating Point Converter網站上玩玩看。

雙精度浮點數

上面講的單精度浮點數只用了32 bit 來表示,為了讓誤差更小,IEEE 754 也定義了如何用64 bit 來表示浮點數,跟32 bit 比起來fraction 部分大了超過兩倍,從23 bit 變成52 bit,所以精準度自然提高許多。

b144fd20-2aef-11ee-a368-dac502259ad0.png

以剛剛不太準的8.9 為例,用64 bit 表示的話雖然可以變得更準,但因為8.9 無法完全寫成2 的次方數相加,到了小數下16 位還是出現誤差,不過跟原本的誤差0.0000003 比起來已經小了很多。

b177a482-2aef-11ee-a368-dac502259ad0.png

類似的情況還有像Python 中的1.0跟0.999...999是相等的、123跟122.999...999也是相等的,因為他們之間的差距已經小到無法放在fraction 里面,所以就二進制的格式看來他們每一個bit 都一樣。

b1a05e40-2aef-11ee-a368-dac502259ad0.png

解決方法

既然無法避免浮點誤差,那就只好跟他共處了(打不過就加入?),這邊提供兩個比較常見的處理方法。

設定最大允許誤差ε (epsilon)

在某些語言里面會提供所謂的epsilon,用來讓你判斷是不是在浮點誤差的允許范圍內,以Python 來說epsilon 的值大概是2.2e-16。

b1c04c00-2aef-11ee-a368-dac502259ad0.png

所以你可以把0.1 + 0.2 == 0.3改寫成0.1 + 0.2 — 0.3 <= epsilon,這樣就能避免浮點誤差在運算過程中作怪,也就可以正確比較出0.1 加0.2 是不是等于0.3。

當然如果系統沒提供的話你也可以自己定義一個epsilon,設定在2 的-15 次方左右。

完全使用十進位進行計算

之所以會有浮點誤差,是因為十進制轉二進制的過程中沒辦法把所有的小數部分都塞進fraction,既然轉換可能會有誤差,那干脆就不要轉了,直接用十進制來做計算!!

在Python 里面有一個module 叫做decimal,它可以幫你用十進位來進行計算,就像你自己用紙筆計算0.1 + 0.2 絕對不會出錯、也不會有任何誤差(其他語言也有類似的模組)。

b1fce94e-2aef-11ee-a368-dac502259ad0.png

自從我用了Decimal 之后不只bug 不見了,連考試也都考一百分了呢!

雖然用十進位進行計算可以完全躲掉浮點誤差,但因為Decimal 的十進位計算是模擬出來的,在最底層的CPU 電路中還是用二進位在進行計算,所以跑起來會比原生的浮點運算慢非常多,所以也不建議全部的浮點運算都用Decimal 來做。

總結

回歸到這篇文章的主題:「為什么浮點誤差是無法避免的?」,相信大家都已經知道了。

至于你說知道IEEE 754 的浮點數格式有什么用嗎?好像也沒什么特別的用處XD,只是覺得能從浮點數的格式來探究誤差的成因很有趣而已,感覺離真相又近了一點點。

而且說不定哪天會有人問我「為什么浮點運算會產生誤差而整數不會」,那時我就可以有自信的講解給他聽,而不是跟他說「反正浮點運算就是會有誤差,背起來就對了」

來源:https://medium.com/starbugs/see-why-floating-point-error-can-not-be-avoided-from-ieee-754-809720b32175 版權歸原作者或平臺所有,僅供學習參考與學術研究,如有侵權,麻煩聯系刪除~感謝







審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 二進制
    +關注

    關注

    2

    文章

    795

    瀏覽量

    41690
  • python
    +關注

    關注

    56

    文章

    4799

    瀏覽量

    84820

原文標題:為什么浮點運算會產生誤差而整數不會?

文章出處:【微信號:最后一個bug,微信公眾號:最后一個bug】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    二進制格雷碼與自然二進制碼的互換分析

    其中采用循環二進制編碼的絕對式編碼器,其輸出信號是一種數字排序,不是權重碼,每一位沒有確定的大小,不能直接進行比較大小和算術運算,也不能直接轉換成其他信號,要經過一次碼變換,變成自然二進制
    的頭像 發表于 09-23 16:23 ?6887次閱讀

    實現兩個二進制除法運算

    實現兩個二進制除法運算,并在八個七段數碼管上進行顯示實現兩個二進制除法運算,并在八個七段數碼管上進行顯示實現兩個二進制除法
    發表于 11-01 20:34

    如何理解二進制運算規則 二進制是如何運算

    二進制運算規則二進制運算算術運算二進制的加法:0+0=0,0+1=1 ,1+0=1, 1+1=
    發表于 12-11 17:49

    二進制數邏輯運算是怎么運算

    “與” , 其結果必為 0; 凡同 1 相“與” , 其結果不變(0 同 1 相“與”仍為 0, 1 同 1 相“與”仍為 1) 。因此, 如果一個 8 位二進制數, 想要保留其中的幾位而屏蔽(清除) 掉其余
    發表于 12-25 16:36

    浮點數轉換為二進制存儲的方法

    浮點數轉換為二進制存儲根據IEEE754標準,單精度float類型使用32比特存儲,其中1位表示符號,8位表示指數,23位表示尾數;雙精度double類型使用64比特存儲,1位符號位,11位指數
    發表于 12-09 06:09

    二進制

    二進制   二進制與十進制的區別在于數碼的個數和進位規律有很大的區別,顧名思義,二進制的計數規律為逢二進一,是以2為基數的計數體制。10這
    發表于 04-06 23:48 ?8210次閱讀
    <b class='flag-5'>二進制</b>

    把截止基極變成異通的二進制觸發器電路圖

    把截止基極變成異通的二進制觸發器電路圖
    發表于 07-03 11:35 ?610次閱讀
    把截止基極<b class='flag-5'>變成</b>異通的<b class='flag-5'>二進制</b>觸發器電路圖

    二進制編碼和二進制數據

    二進制編碼和二進制數據   二進制編碼是計算機內使用最多的碼制,它只使用兩個基本符號"0"和"1",并且通過由這兩個符號組成的
    發表于 10-13 16:22 ?4808次閱讀

    二進制數的運算規則

    二進制數的運算規則  二進制數之間可以執行算術運算和邏輯運算,其規則簡單,容易實現。  (1) 加法運算
    發表于 10-13 16:24 ?2.3w次閱讀

    二進制電平,什么是二進制電平

    二進制電平,什么是二進制電平 在二進制數字通信系統中,每個碼元或每個符號只能是“1”和“0”兩個狀態之一。若將每個碼元可能取的狀態增
    發表于 03-17 16:51 ?2365次閱讀

    二進制數值數據的編碼與運算算法

    二進制數值數據的編碼與運算算法 一、原碼、反碼、補碼的定義 1、原碼的定義 2、補碼的定義
    發表于 04-15 14:42 ?2929次閱讀

    二進制加法程序【匯編版】

    二進制加法程序【匯編版】二進制加法程序【匯編版】二進制加法程序【匯編版】二進制加法程序【匯編版】
    發表于 12-29 11:02 ?0次下載

    二進制邏輯運算詳解

    二進制運行詳解
    發表于 02-14 16:56 ?13次下載

    浮點數轉換為二進制存儲

    浮點數轉換為二進制存儲根據IEEE754標準,單精度float類型使用32比特存儲,其中1位表示符號,8位表示指數,23位表示尾數;雙精度double類型使用64比特存儲,1位符號位,11位指數
    發表于 11-26 11:21 ?52次下載
    <b class='flag-5'>浮點</b>數轉換為<b class='flag-5'>二進制</b>存儲

    如何實現二進制和BCD碼數據的相互轉變

    如何實現二進制和BCD碼數據的相互轉變二進制碼是將十進制數字表示為二進制數和十進制數的一種表
    的頭像 發表于 02-18 14:51 ?3740次閱讀
    主站蜘蛛池模板: 3DNagoonimation动漫| 欧美三级黄色大片| 午夜在线视频国产极品片| 国产精品久久久久久久人人看 | 翁公与小莹在客厅激情| 欧美美女一区二区三区| 免费播放美女一级毛片| 麻豆一二三区果冻| 美女露出撒尿的部位| 美女脱内衣裸身尿口露出来| 老版香蕉版下载| 免费精品美女久久久久久久久| 蜜臀AV人妻久久无码精品麻豆| 母乳女神春日もな| 欧美日韩精品| 日韩人妻无码精品-专区| 色偷偷爱偷偷要| 午夜福利免费院| 小骚妇BBBXXX| 亚洲欧美精品一中文字幕 | 久久99国产亚洲高清观着| 精品伊人久久久| 久久永久影院免费| 免费亚洲视频在线观看| 欧美在线看费视频在线| 日韩欧美一区二区中文字幕| 四虎一级片| 亚洲精品123区在线观看| 一区二区三区四区国产| 131美女爱做视频午夜剧场| 99视频在线观看免费| 岛国大片在线观看免费版| 国产日韩高清一区二区三区| 灰原哀被啪漫画禁漫| 久久综合网久久综合| 欧美一级久久久久久久久大| 手机看片国产免费| 亚洲色偷偷偷网站色偷一区人人藻 | 狠狠色狠狠色狠狠五月ady| 久久99综合国产精品亚洲首页| 领导边摸边吃奶边做爽在线观看|