浮點數精度的轉換

2021-09-06 06:54:42 字數 3351 閱讀 1913

x86/x64

體系裡,由於

x87 fpu

硬體使用擴充套件雙精度格式,因此必然會遇到

single/double precision

格式與double extended-precision

格式之間的互換問題。

轉換為擴充套件雙精度數

當由單精度數或雙精度轉換為擴充套件雙精度數時,

exponent

部分必須基於擴充套件雙精度數的

biased

碼來調整。於是擴充套件雙精度數的

exponent

值為:①

從單精度轉化:

exponent – 127 + 16383。②

從雙精度轉化:

exponent – 1023 + 16383

。而擴充套件雙精度數的

significand

部分,由單

/雙精度數的

significand

部分移植過來。

以單精度數

1.11...×2120

為例,它轉換為擴充套件雙精度的過程如下所示。

單精度數

1.11...×2120

的編碼值為

0x7bffffff

,它的exponent

值為0xf7

(11110111b

),significand

部分全為1值。

於是擴充套件雙精度數的

exponent

值為0xf7

-127 + 16383=0x4077

(1000 0000 0111 0111b

),單精度

23位的

significand

部分直接移到擴充套件雙精度的

bit62

到bit40

位,低40位補0

。最終的擴充套件雙精度編碼值為

0x4077_ffffff00_00000000

。而對於雙精度數來說:

52位的

significand

部分將直接移到擴充套件雙精度的

bit62

到bit11

位。擴充套件雙精度數轉換為單精度數

而從擴充套件雙精度轉換為單

/雙精度數的情形會複雜得多,涉及目標格式的

precison

(精度)問題。當擴充套件雙精度

significand

部分的值超出目標格式的精度時,就會發生

rounded

(捨入)操作,從而引發

precision

異常。要檢查超出精度的

significand

是否為0

值,如下所示。

目標格式

超出精度部分 備註

單精度數

bit 39

~bit 0

是否為0值

雙精度數

bit 10

~bit 0

這部分不為

0值時,就會發生

rounded

操作。下面,我們以擴充套件雙精度數

1.11...×2120

轉化為單精度格式為例進行描述。當

1.11...×2120

為擴充套件雙精度格式時,它的編碼值為

0x4077_ffffffff_ffffffff

。目標格式

exponent

部分的計算如下。

①單精度數:

exponent

-16383+127。②

雙精度數:

exponent

-16383+1023

。這個轉換過程較為複雜,如下所示。

圖中的陰影部分是超出精度的

significand

部分(bit 39

~bit 0

),它的值不為

0,需要進行

rounded

操作,在

x87 fpu

中這個捨入依賴於

rounded

控制位。

ieee754

定義了以下

4種捨入模式。

round to nearest

模式:朝±∞(正和負方向的無窮大值)方向捨入。

round down模式:正數朝最大

normal

值捨入,負數朝

-∞方向捨入。

round up模式:正數朝

+∞方向捨入

,負數朝最大

normal

值捨入。

round zero模式:正數和負數都朝最大

normal

值捨入。

上圖中的捨入是朝

+∞方向捨入,如圖所示:

bit 39

的值為1

,它將向

bit 40

進行捨入,效果等於

+1值。目標格式中的

significand

部分捨入的結果值為0。

目標格式的

exponent

部分為擴充套件雙精度的

exponent-16383+127=0xf7

(11110111b

),可是由於

significand

部分還是進製值,因此目標格式的最終

exponent

部分為0xf8

(加上1

值)。因此,最終轉換的單精度值為

0x7c000000

,轉換得到的浮點數是

1.0...×2

121,

結果大於原來的擴充套件雙精度浮點數。

擴充套件雙精度數轉換為雙精度數

這和轉換為單精度數是一致的。在雙精度格式裡,它的精度是

52位,因此超出精度部分為

bit10

到bit0

位。exponent

的計算是擴充套件雙精度的

exponent-16383+1023

。本文節選自《

x86x64

體系探索及程式設計》

電子工業出版社出版

鄧志著

浮點數精度問題

一 例子 首先我們去編譯器試試 double a 1.9 通過新增監視檢視a的值 會發現a的值是1.8999999 二 開始今天的學習 在最開始學c 的時候並沒有對浮點數進行很深入的學習,認為浮點不就是小數嘛,首先在c 的巨集裡面有 flt max 和 flt min 的定義,float是四位元組的...

浮點數精度之謎

話要從業務 裡的bug說起,大致過程是前端運算 2.07 1 之後結果卻是1.0699999999999998,老司機們都知道是浮點數運算的精度丟失導致的,在檢視了下具體 果然處理不當。因此我深究一番,並誕生了此文。此處重點強調兩個認識誤區 首先不得不說說浮點數的表示方法,任何數在計算機面前都會被處...

PHP 浮點數的精度

浮點數的精度有限。儘管取決於系統,php 通常使用 ieee 754 雙精度格式,則由於取整而導致的最大相對誤差為 1.11e 16。非基本數 算可能會給出更大誤差,並且要考慮到進行復合運算時的誤差傳遞。此外,以十進位制能夠精確表示的有理數如 0.1 或 0.7,無論有多少尾數都不能被內部所使用的二...