亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

當'%b'動詞是浮數時,它的輸出是什么

當'%b'動詞是浮數時,它的輸出是什么

Go
眼眸繁星 2022-09-19 20:47:36
根據go文檔,與浮數一起使用意味著:%b無十進制的科學記數法,指數為2的冪,以strconv的方式。格式浮動為“b”格式,例如 -123456p-78如下代碼所示,程序輸出為8444249301319680P-51我對浮數有點困惑,誰能告訴我這個結果是如何計算的?這是什么意思?%bp-f := 3.75fmt.Printf("%b\n", f)fmt.Println(strconv.FormatFloat(f, 'b', -1, 64))
查看完整描述

3 回答

?
白板的微信

TA貢獻1883條經驗 獲得超3個贊

這意味著:decimalless scientific notation with exponent a power of two

8444249301319680*(2^-51) = 3.75 or 8444249301319680/(2^51) = 3.75

p-51均值,也可以計算為2^-511/(2^51)

關于浮點算術的好文章。https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html


查看完整回答
反對 回復 2022-09-19
?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

值得指出的是,由于浮點數的內部存儲格式,運行時系統也特別容易生成輸出。%b

如果我們忽略“非規范化”的浮點數(我們可以稍后將它們加回來),浮點數在內部存儲為1.bbbbbb...對于某些位集(此處為“b”),bbb x 2exp,例如,值 4 存儲為 。值 6 存儲為 ,值 7 存儲為 ,八 存儲為 。值七分半是,七和四分之三是,依此類推。這里的每個位,在1.bbbb中,代表低于指數的2的下一個冪。1.000...000 <exp> 21.100...000 <exp> 21.110...000 <exp> 21.000...000 <exp> 31.111 <exp> 21.1111 <exp> 2

要使用格式打印出來,我們只需注意,我們需要連續四位,即值15十進制或0xf或二進制,這導致指數需要減少3,因此我們希望乘以2-1或1/2,而不是乘以22或4。因此,我們可以取實際的指數(2),減去3(因為我們移動“點”三次以打印二進制或15),從而打印出字符串 。1.111 <exp> 2%b11111111115p-1

不過,這不是Go的印刷品:它打印 。這是相同的值(所以任何一個都是正確的輸出)——但為什么呢?%b8444249301319680p-50

好吧,是,在十六進制中,.擴展到完整的二進制,這是 。這是53個二進制數字。為什么53個二進制數字,而四個就足夠了?84442493013196801E0000000000001 1110 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

答案可以在Nick的答案中的鏈接中找到:IEEE 754浮點格式使用53位的“尾數”或“有效數”(后者是更好的術語,也是我通常嘗試使用的術語,但你會看到前者經常彈出)。也就是說,有52 s,加上那個強行引入的領先者。因此,始終有 53 個二進制數字(對于 IEEE“雙精度”)。1.bbb...bbbb1

如果我們只是把這個53進制數字視為十進制數,我們總是可以在沒有小數點的情況下打印出來。這意味著我們只需調整兩個指數的冪。

在IEEE754格式中,指數本身已經以“多余的形式”存儲,并添加了1023(再次用于雙精度)。這意味著它實際上以指數值為2 + 1023 = 1025存儲。這意味著,為了獲得2的實際冪,格式化數字的機器代碼已經必須減去1023。我們可以讓它同時再減去52。1.111000...000 <exp> 2

最后,由于隱含的始終存在,因此內部IEEE754編號實際上并不存儲該位。因此,要讀出值并對其進行轉換,代碼在內部執行以下操作:11

decimalPart := machineDependentReinterpretation1(&doubleprec_value)
expPart := machineDependentReinterpretation2(&doubleprec_value)

其中,依賴于機器的重新解釋只是提取正確的位,根據需要在小數部分放入隱含位,減去指數部分的偏移量(1023 + 52),然后執行以下操作:1

fmt.Sprint("%dp%d", decimalPart, expPart)

當以十進制打印浮點數時,基數轉換(從基數 2 到基數 10)是有問題的,需要大量的代碼才能正確舍入。像這樣以二進制格式打印它要容易得多。

為讀者提供的練習,以幫助理解這一點:

  1. 計算 1.102 x 22。注:1.12 為十進制 11/2。

  2. 計算 11.02 x 21。(11.02 是 3。

  3. 基于上述內容,當您左右“滑動二進制點”時會發生什么?

  4. (更難)為什么我們可以假設一個領先的1?如有必要,請繼續閱讀。

為什么我們可以假設一個領先的1?

讓我們首先注意,當我們使用十進制的科學記數法時,我們不能假設一個前導。數字可能是 1.7 x 103,或 5.1 x 105,或者其他什么。但是,當我們“正確”使用科學記數法時,第一個數字永遠不會為。也就是說,我們不寫0.3 x 100,而是寫3.0 x 10-1。在這種表示法中,位數告訴我們精度,第一個數字永遠不必為零,通常也不應該是零。如果第一個數字為零,我們只需移動小數點并調整指數(請參閱上面的練習 1 和 2)。1

同樣的規則也適用于浮點數。例如,我們不存儲,而是將二進制點滑動到兩個位置上并得到,并將指數減小2。如果我們可能想要存儲,我們將二進制點向另一個位置滑動并增加指數。每當我們這樣做時,第一個數字最終總是一個0.011.0011.1

這里有一個很大的例外,那就是:當我們這樣做時,我們不能存儲零!因此,我們不會對數字這樣做。在 IEEE754 中,我們存儲為全零位(符號除外,我們可以將其設置為存儲 )。這有一個全零指數,計算機硬件將其作為特殊情況處理。0.00.0-0.0

非規范化數字:當我們不能假設前導 1 時

這個系統有一個明顯的缺陷(不能完全通過去規范來解決,但盡管如此,IEEE也有去規范)。也就是說:我們可以存儲的最小數字“突然下溢”為零。Kahan有一個關于逐漸下溢的15頁“簡短教程”,我不打算試圖總結,但是當我們達到最小允許指數(2-1023)并希望“變小”時,IEEE讓我們停止使用這些帶有前導位的“規范化”數字。1

這不會影響 Go 本身格式化浮點數的方式,因為 Go 只是“按原樣”獲取整個有效數。我們所要做的就是停止插入253“隱含1”,當輸入值是非規范化的數字時,其他一切都只是工作。我們可以將這種魔力隱藏在依賴于機器的重新解釋代碼中,或者在Go中顯式執行,以更方便的方式為準。float64


查看完整回答
反對 回復 2022-09-19
?
慕容708150

TA貢獻1831條經驗 獲得超4個贊

科學記數法的五條規則如下:

  1. 基數始終為 10

  2. 指數必須是非零整數,這意味著它可以是正數或負數

  3. 系數的絕對值大于或等于 1,但應小于 10

  4. 系數帶有符號 (+) 或 (-)

  5. 曼蒂薩攜帶其余的有效數字

p

  • %b指數為2的冪的科學記數法(其p)

  • %e科學記數法


查看完整回答
反對 回復 2022-09-19
  • 3 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號