日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于浮点数的原理详解

發(fā)布時(shí)間:2025/3/20 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于浮点数的原理详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 什么是浮點(diǎn)數(shù)

在計(jì)算機(jī)系統(tǒng)的發(fā)展過程中,曾經(jīng)提出過多種方法表達(dá)實(shí)數(shù)。典型的比如相對于浮點(diǎn)數(shù)的定點(diǎn)數(shù)(Fixed Point Number)。在這種表達(dá)方式中,小數(shù)點(diǎn)固定的位于實(shí)數(shù)所有數(shù)字中間的某個(gè)位置。貨幣的表達(dá)就可以使用這種方式,比如 99.00 或者 00.99 可以用于表達(dá)具有四位精度(Precision),小數(shù)點(diǎn)后有兩位的貨幣值。由于小數(shù)點(diǎn)位置固定,所以可以直接用四位數(shù)值來表達(dá)相應(yīng)的數(shù)值。SQL 中的 NUMBER 數(shù)據(jù)類型就是利用定點(diǎn)數(shù)來定義的。還有一種提議的表達(dá)方式為有理數(shù)表達(dá)方式,即用兩個(gè)整數(shù)的比值來表達(dá)實(shí)數(shù)。

定點(diǎn)數(shù)表達(dá)法的缺點(diǎn)在于其形式過于僵硬,固定的小數(shù)點(diǎn)位置決定了固定位數(shù)的整數(shù)部分和小數(shù)部分,不利于同時(shí)表達(dá)特別大的數(shù)或者特別小的數(shù)。最終,絕大多數(shù)現(xiàn)代的計(jì)算機(jī)系統(tǒng)采納了所謂的浮點(diǎn)數(shù)表達(dá)方式。這種表達(dá)方式利用科學(xué)計(jì)數(shù)法來表達(dá)實(shí)數(shù),即用一個(gè)尾數(shù)(Mantissa ),一個(gè)基數(shù)(Base),一個(gè)指數(shù)(Exponent)以及一個(gè)表示正負(fù)的符號來表達(dá)實(shí)數(shù)。比如 123.45 用十進(jìn)制科學(xué)計(jì)數(shù)法可以表達(dá)為 1.2345 × 102?,其中 1.2345 為尾數(shù),10 為基數(shù),2 為指數(shù)。浮點(diǎn)數(shù)利用指數(shù)達(dá)到了浮動小數(shù)點(diǎn)的效果,從而可以靈活地表達(dá)更大范圍的實(shí)數(shù)。

提示:?尾數(shù)有時(shí)也稱為有效數(shù)字(Significand)。尾數(shù)實(shí)際上是有效數(shù)字的非正式說法。

同樣的數(shù)值可以有多種浮點(diǎn)數(shù)表達(dá)方式,比如上面例子中的 123.45 可以表達(dá)為 12.345 × 101,0.12345 × 103?或者 1.2345 × 102。因?yàn)檫@種多樣性,有必要對其加以規(guī)范化以達(dá)到統(tǒng)一表達(dá)的目標(biāo)。規(guī)范的(Normalized)浮點(diǎn)數(shù)表達(dá)方式具有如下形式:

±d.dd...d?× β?e?, (0 ≤?d?i?< β)

其中?d.dd...d?即尾數(shù),β 為基數(shù),e?為指數(shù)。尾數(shù)中數(shù)字的個(gè)數(shù)稱為精度,在本文中用?p?來表示。每個(gè)數(shù)字?d?介于 0 和基數(shù)之間,包括 0。小數(shù)點(diǎn)左側(cè)的數(shù)字不為 0。

基于規(guī)范表達(dá)的浮點(diǎn)數(shù)對應(yīng)的具體值可由下面的表達(dá)式計(jì)算而得:

±(d?0?+?d?1β-1?+ ... +?d?p-1β-(p-1)?e?, (0 ≤?d?i?< β)

對于十進(jìn)制的浮點(diǎn)數(shù),即基數(shù) β 等于 10 的浮點(diǎn)數(shù)而言,上面的表達(dá)式非常容易理解,也很直白。計(jì)算機(jī)內(nèi)部的數(shù)值表達(dá)是基于二進(jìn)制的。從上面的表達(dá)式,我們可以知道,二進(jìn)制數(shù)同樣可以有小數(shù)點(diǎn),也同樣具有類似于十進(jìn)制的表達(dá)方式。只是此時(shí) β 等于 2,而每個(gè)數(shù)字?d?只能在 0 和 1 之間取值。比如二進(jìn)制數(shù) 1001.101 相當(dāng)于 1 × 2?3?+ 0 × 22?+ 0 × 21?+ 1 × 20?+ 1 × 2-1?+ 0 × 2-2?+ 1 × 2-3,對應(yīng)于十進(jìn)制的 9.625。其規(guī)范浮點(diǎn)數(shù)表達(dá)為 1.001101 × 23

2. IEEE 浮點(diǎn)數(shù)

計(jì)算機(jī)中是用有限的連續(xù)字節(jié)保存浮點(diǎn)數(shù)的。保存這些浮點(diǎn)數(shù)當(dāng)然必須有特定的格式,Java 平臺上的浮點(diǎn)數(shù)類型?float?和?double?采納了 IEEE 754 標(biāo)準(zhǔn)中所定義的單精度 32 位浮點(diǎn)數(shù)和雙精度 64 位浮點(diǎn)數(shù)的格式。

注意:?Java 平臺還支持該標(biāo)準(zhǔn)定義的兩種擴(kuò)展格式,即 float-extended-exponent 和 double-extended-exponent 擴(kuò)展格式。這里將不作介紹,有興趣的讀者可以參考相應(yīng)的參考資料。

在 IEEE 標(biāo)準(zhǔn)中,浮點(diǎn)數(shù)是將特定長度的連續(xù)字節(jié)的所有二進(jìn)制位分割為特定寬度的符號域,指數(shù)域和尾數(shù)域三個(gè)域,其中保存的值分別用于表示給定二進(jìn)制浮點(diǎn)數(shù)中的符號,指數(shù)和尾數(shù)。這樣,通過尾數(shù)和可以調(diào)節(jié)的指數(shù)(所以稱為"浮點(diǎn)")就可以表達(dá)給定的數(shù)值了。具體的格式參見下面的圖例:

在上面的圖例中,第一個(gè)域?yàn)榉栍颉F渲?0 表示數(shù)值為正數(shù),而 1 則表示負(fù)數(shù)。

第二個(gè)域?yàn)橹笖?shù)域,對應(yīng)于我們之前介紹的二進(jìn)制科學(xué)計(jì)數(shù)法中的指數(shù)部分。其中單精度數(shù)為 8 位,雙精度數(shù)為 11 位。以單精度數(shù)為例,8 位的指數(shù)為可以表達(dá) 0 到 255 之間的 255 個(gè)指數(shù)值。但是,指數(shù)可以為正數(shù),也可以為負(fù)數(shù)。為了處理負(fù)指數(shù)的情況,實(shí)際的指數(shù)值按要求需要加上一個(gè)偏差(Bias)值作為保存在指數(shù)域中的值,單精度數(shù)的偏差值為 127,而雙精度數(shù)的偏差值為 1023。比如,單精度的實(shí)際指數(shù)值 0 在指數(shù)域中將保存為 127;而保存在指數(shù)域中的 64 則表示實(shí)際的指數(shù)值 -63。 偏差的引入使得對于單精度數(shù),實(shí)際可以表達(dá)的指數(shù)值的范圍就變成 -127 到 128 之間(包含兩端)。我們不久還將看到,實(shí)際的指數(shù)值 -127(保存為 全 0)以及 +128(保存為全 1)保留用作特殊值的處理。這樣,實(shí)際可以表達(dá)的有效指數(shù)范圍就在 -127 和 127 之間。在本文中,最小指數(shù)和最大指數(shù)分別用?emin?和?emax?來表達(dá)。

圖例中的第三個(gè)域?yàn)槲矓?shù)域,其中單精度數(shù)為 23 位長,雙精度數(shù)為 52 位長。除了我們將要講到的某些特殊值外,IEEE 標(biāo)準(zhǔn)要求浮點(diǎn)數(shù)必須是規(guī)范的。這意味著尾數(shù)的小數(shù)點(diǎn)左側(cè)必須為 1,因此我們在保存尾數(shù)的時(shí)候,可以省略小數(shù)點(diǎn)前面這個(gè) 1,從而騰出一個(gè)二進(jìn)制位來保存更多的尾數(shù)。這樣我們實(shí)際上用 23 位長的尾數(shù)域表達(dá)了 24 位的尾數(shù)。比如對于單精度數(shù)而言,二進(jìn)制的 1001.101(對應(yīng)于十進(jìn)制的 9.625)可以表達(dá)為 1.001101 × 23,所以實(shí)際保存在尾數(shù)域中的值為 00110100000000000000000,即去掉小數(shù)點(diǎn)左側(cè)的 1,并用 0 在右側(cè)補(bǔ)齊。

值得注意的是,對于單精度數(shù),由于我們只有 24 位的指數(shù)(其中一位隱藏),所以可以表達(dá)的最大指數(shù)為 224?- 1 = 16,777,215。特別的,16,777,216 是偶數(shù),所以我們可以通過將它除以 2 并相應(yīng)地調(diào)整指數(shù)來保存這個(gè)數(shù),這樣 16,777,216 同樣可以被精確的保存。相反,數(shù)值 16,777,217 則無法被精確的保存。由此,我們可以看到單精度的浮點(diǎn)數(shù)可以表達(dá)的十進(jìn)制數(shù)值中,真正有效的數(shù)字不高于 8 位。事實(shí)上,對相對誤差的數(shù)值分析結(jié)果顯示有效的精度大約為 7.22 位。參考下面的示例:

???????? true value???????????????? stored value--------------------------------------16,777,215???????????????? 1.6777215E716,777,216???????????????? 1.6777216E716,777,217???????????????? 1.6777216E716,777,218???????????????? 1.6777218E716,777,219???????????????? 1.677722E716,777,220???????????????? 1.677722E716,777,221???????????????? 1.677722E716,777,222???????????????? 1.6777222E716,777,223???????????????? 1.6777224E716,777,224???????????????? 1.6777224E716,777,225???????????????? 1.6777224E7--------------------------------------

根據(jù)標(biāo)準(zhǔn)要求,無法精確保存的值必須向最接近的可保存的值進(jìn)行舍入。這有點(diǎn)像我們熟悉的十進(jìn)制的四舍五入,即不足一半則舍,一半以上(包括一半)則進(jìn)。不過對于二進(jìn)制浮點(diǎn)數(shù)而言,還多一條規(guī)矩,就是當(dāng)需要舍入的值剛好是一半時(shí),不是簡單地進(jìn),而是在前后兩個(gè)等距接近的可保存的值中,取其中最后一位有效數(shù)字為零者。從上面的示例中可以看出,奇數(shù)都被舍入為偶數(shù),且有舍有進(jìn)。我們可以將這種舍入誤差理解為"半位"的誤差。所以,為了避免 7.22 對很多人造成的困惑,有些文章經(jīng)常以 7.5 位來說明單精度浮點(diǎn)數(shù)的精度問題。

提示:?這里采用的浮點(diǎn)數(shù)舍入規(guī)則有時(shí)被稱為舍入到偶數(shù)(Round to Even)。相比簡單地逢一半則進(jìn)的舍入規(guī)則,舍入到偶數(shù)有助于從某些角度減小計(jì)算中產(chǎn)生的舍入誤差累積問題。因此為 IEEE 標(biāo)準(zhǔn)所采用。

2樓 昕晨?發(fā)表于:2007-7-15 20:26:00

3. 實(shí)數(shù)和浮點(diǎn)數(shù)之間的變換

現(xiàn)在我們已經(jīng)明白了浮點(diǎn)數(shù)的 IEEE 表達(dá)方式。我們來做些實(shí)數(shù)和浮點(diǎn)數(shù)之間的變換練習(xí)以加深理解。在這些練習(xí)中,你還會發(fā)現(xiàn)一些圍繞浮點(diǎn)數(shù)運(yùn)算的令人吃驚的事實(shí)。

首先我們來看看事情簡單的一面,從浮點(diǎn)數(shù)變換到實(shí)數(shù)。理解了浮點(diǎn)數(shù)的格式,做這個(gè)練習(xí)并不難。假定我們有一個(gè) 32 位的數(shù)據(jù),用十六進(jìn)制表示為 0xC0B40000,并且我們知道它實(shí)際上是一個(gè)單精度的浮點(diǎn)數(shù)。為了得到該浮點(diǎn)數(shù)實(shí)際表達(dá)的實(shí)數(shù),我們首先將它變換為二進(jìn)制形式:

?? C???? 0???? B???? 4???? 0???? 0???? 0???? 0 1100 0000 1011 0100 0000 0000 0000 0000

接著按照浮點(diǎn)數(shù)的格式切分為相應(yīng)的域:

1?? 10000001 01101000000000000000000

符號域 1 意味著負(fù)數(shù);指數(shù)域?yàn)?129 意味著實(shí)際的指數(shù)為 2 (減去偏差值 127);尾數(shù)域?yàn)?01101 意味著實(shí)際的二進(jìn)制尾數(shù)為 1.01101 (加上隱含的小數(shù)點(diǎn)前面的 1)。所以,實(shí)際的實(shí)數(shù)為:

-1.01101 × 22 -(20 + 2-2 + 2-3 2-5) × 22 -5.625

從實(shí)數(shù)向浮點(diǎn)數(shù)變換稍微麻煩一點(diǎn)。假定我們需要將實(shí)數(shù) -9.625 表達(dá)為單精度的浮點(diǎn)數(shù)格式。方法是首先將它用二進(jìn)制浮點(diǎn)數(shù)表達(dá),然后變換為相應(yīng)的浮點(diǎn)數(shù)格式。

首先,將小數(shù)點(diǎn)左側(cè)的整數(shù)部分變換為其二進(jìn)制形式,9 的二進(jìn)制性形式為 1001。處理小數(shù)部分的算法是將我們的小數(shù)部分乘以基數(shù) 2,記錄乘積結(jié)果的整數(shù)部分,接著將結(jié)果的小數(shù)部分繼續(xù)乘以 2,并不斷繼續(xù)該過程:

0.625 × 2 = 1.25???????? 1 0.25?? × 2 = 0.5???????? 0 0.5?? × 2 = 1?????????? 1 0

當(dāng)最后的結(jié)果為零時(shí),結(jié)束這個(gè)過程。這時(shí)右側(cè)的一列數(shù)字就是我們所需的二進(jìn)制小數(shù)部分,即 0.101。這樣,我們就得到了完整的二進(jìn)制形式 1001.101。用規(guī)范浮點(diǎn)數(shù)表達(dá)為 1.001101 × 23

因?yàn)槭秦?fù)數(shù),所以符號域?yàn)?1。指數(shù)為 3,所以指數(shù)域?yàn)?3 + 127 = 130,即二進(jìn)制的 10000010。尾數(shù)省略掉小數(shù)點(diǎn)左側(cè)的 1 之后為 001101,右側(cè)用零補(bǔ)齊。最終結(jié)果為:

1 10000010 00110100000000000000000

最后可以將浮點(diǎn)數(shù)形式表示為十六進(jìn)制的數(shù)據(jù)如下:

1100 0001 0001 1010 0000 0000 0000 0000C???? 1???? 1???? A???? 0???? 0???? 0???? 0

最終結(jié)果為 0xC11A0000。

很簡單?等等!你可能已經(jīng)注意到了,在上面這個(gè)我們有意選擇的示例中,不斷的將產(chǎn)生的小數(shù)部分乘以 2 的過程掩蓋了一個(gè)事實(shí)。該過程結(jié)束的標(biāo)志是小數(shù)部分乘以 2 的結(jié)果為 1,不難想象,很多小數(shù)根本不能經(jīng)過有限次這樣的過程而得到結(jié)果(比如最簡單的 0.1)。我們已經(jīng)知道浮點(diǎn)數(shù)尾數(shù)域的位數(shù)是有限的,為此,浮點(diǎn)數(shù)的處理辦法是持續(xù)該過程直到由此得到的尾數(shù)足以填滿尾數(shù)域,之后對多余的位進(jìn)行舍入。換句話說,除了我們之前講到的精度問題之外,十進(jìn)制到二進(jìn)制的變換也并不能保證總是精確的,而只能是近似值。事實(shí)上,只有很少一部分十進(jìn)制小數(shù)具有精確的二進(jìn)制浮點(diǎn)數(shù)表達(dá)。再加上浮點(diǎn)數(shù)運(yùn)算過程中的誤差累積,結(jié)果是很多我們看來非常簡單的十進(jìn)制運(yùn)算在計(jì)算機(jī)上卻往往出人意料。這就是最常見的浮點(diǎn)運(yùn)算的"不準(zhǔn)確"問題。參見下面的 Java 示例:

System.out.print("34.6-34.0=" + (34.6f-34.0f));

這段代碼的輸出結(jié)果如下:

34.6-34.0=0.5999985

產(chǎn)生這個(gè)誤差的原因是 34.6 無法精確的表達(dá)為相應(yīng)的浮點(diǎn)數(shù),而只能保存為經(jīng)過舍入的近似值。這個(gè)近似值與 34.0 之間的運(yùn)算自然無法產(chǎn)生精確的結(jié)果。

4. 特殊值

通過前面的介紹,你應(yīng)該已經(jīng)了解的浮點(diǎn)數(shù)的基本知識,這些知識對于一個(gè)不接觸浮點(diǎn)數(shù)應(yīng)用的人應(yīng)該足夠了。不過,如果你興趣正濃,或者面對著一個(gè)棘手的浮點(diǎn)數(shù)應(yīng)用,可以通過本節(jié)了解到關(guān)于浮點(diǎn)數(shù)的一些值得注意的特殊之處。

我們已經(jīng)知道,指數(shù)域?qū)嶋H可以表達(dá)的指數(shù)值的范圍為 -127 到 128 之間(包含兩端)。其中,值 -127(保存為 全 0)以及 +128(保存為全 1)保留用作特殊值的處理。本節(jié)將詳細(xì) IEEE 標(biāo)準(zhǔn)中所定義的這些特殊值。

浮點(diǎn)數(shù)中的特殊值主要用于特殊情況或者錯(cuò)誤的處理。比如在程序?qū)σ粋€(gè)負(fù)數(shù)進(jìn)行開平方時(shí),一個(gè)特殊的返回值將用于標(biāo)記這種錯(cuò)誤,該值為 NaN(Not a Number)。沒有這樣的特殊值,對于此類錯(cuò)誤只能粗暴地終止計(jì)算。除了 NaN 之外,IEEE 標(biāo)準(zhǔn)還定義了 ±0,±∞ 以及非規(guī)范化數(shù)(Denormalized Number)。

對于單精度浮點(diǎn)數(shù),所有這些特殊值都由保留的特殊指數(shù)值 -127 和 128 來編碼。如果我們分別用?emin?和?emax?來表達(dá)其它常規(guī)指數(shù)值范圍的邊界,即 -126 和 127,則保留的特殊指數(shù)值可以分別表達(dá)為?emin?- 1 和?emax?+ 1; 。基于這個(gè)表達(dá)方式,IEEE 標(biāo)準(zhǔn)的特殊值如下所示:

其中?f?表示尾數(shù)中的小數(shù)點(diǎn)右側(cè)的(Fraction)部分。第一行即我們之前介紹的普通的規(guī)范化浮點(diǎn)數(shù)。隨后我們將分別對余下的特殊值加以介紹。

4.1. NaN

NaN 用于處理計(jì)算中出現(xiàn)的錯(cuò)誤情況,比如 0.0 除以 0.0 或者求負(fù)數(shù)的平方根。由上面的表中可以看出,對于單精度浮點(diǎn)數(shù),NaN 表示為指數(shù)為?emax?+ 1 = 128(指數(shù)域全為 1),且尾數(shù)域不等于零的浮點(diǎn)數(shù)。IEEE 標(biāo)準(zhǔn)沒有要求具體的尾數(shù)域,所以 NaN 實(shí)際上不是一個(gè),而是一族。不同的實(shí)現(xiàn)可以自由選擇尾數(shù)域的值來表達(dá) NaN,比如 Java 中的常量?Float.NaN?的浮點(diǎn)數(shù)可能表達(dá)為 01111111110000000000000000000000,其中尾數(shù)域的第一位為 1,其余均為 0(不計(jì)隱藏的一位),但這取決系統(tǒng)的硬件架構(gòu)。Java 中甚至允許程序員自己構(gòu)造具有特定位模式的 NaN 值(通過?Float.intBitsToFloat()?方法)。比如,程序員可以利用這種定制的 NaN 值中的特定位模式來表達(dá)某些診斷信息。

定制的 NaN 值,可以通過?Float.isNaN()?方法判定其為 NaN,但是它和 Float.NaN 常量卻不相等。實(shí)際上,所有的 NaN 值都是無序的。數(shù)值比較操作符 <,<=,> 和 >= 在任一操作數(shù)為 NaN 時(shí)均返回?false。等于操作符 == 在任一操作數(shù)為 NaN 時(shí)均返回?false,即使是兩個(gè)具有相同位模式的 NaN 也一樣。而操作符 != 則當(dāng)任一操作數(shù)為 NaN 時(shí)返回?true。這個(gè)規(guī)則的一個(gè)有趣的結(jié)果是?x!=x?當(dāng) x 為 NaN 時(shí)竟然為真。

可以產(chǎn)生 NaN 的操作如下所示:

此外,任何有 NaN 作為操作數(shù)的操作也將產(chǎn)生 NaN。用特殊的 NaN 來表達(dá)上述運(yùn)算錯(cuò)誤的意義在于避免了因這些錯(cuò)誤而導(dǎo)致運(yùn)算的不必要的終止。比如,如果一個(gè)被循環(huán)調(diào)用的浮點(diǎn)運(yùn)算方法,可能由于輸入的參數(shù)問題而導(dǎo)致發(fā)生這些錯(cuò)誤,NaN 使得 即使某次循環(huán)發(fā)生了這樣的錯(cuò)誤,也可以簡單地繼續(xù)執(zhí)行循環(huán)以進(jìn)行那些沒有錯(cuò)誤的運(yùn)算。你可能想到,既然 Java 有異常處理機(jī)制,也許可以通過捕獲并忽略異常達(dá)到相同的效果。但是,要知道,IEEE 標(biāo)準(zhǔn)不是僅僅為 Java 而制定的,各種語言處理異常的機(jī)制不盡相同,這將使得代碼的遷移變得更加困難。何況,不是所有語言都有類似的異常或者信號(Signal)處理機(jī)制。

注意:?Java 中,不同于浮點(diǎn)數(shù)的處理,整數(shù)的 0 除以 0 將拋出?java.lang.ArithmeticException?異常。

4.2. 無窮

和 NaN 一樣,特殊值無窮(Infinity)的指數(shù)部分同樣為?emax?+ 1 = 128,不過無窮的尾數(shù)域必須為零。無窮用于表達(dá)計(jì)算中產(chǎn)生的上溢(Overflow)問題。比如兩個(gè)極大的數(shù)相乘時(shí),盡管兩個(gè)操作數(shù)本身可以用保存為浮點(diǎn)數(shù),但其結(jié)果可能大到無法保存為浮點(diǎn)數(shù),而必須進(jìn)行舍入。根據(jù) IEEE 標(biāo)準(zhǔn),此時(shí)不是將結(jié)果舍入為可以保存的最大的浮點(diǎn)數(shù)(因?yàn)檫@個(gè)數(shù)可能離實(shí)際的結(jié)果相差太遠(yuǎn)而毫無意義),而是將其舍入為無窮。對于負(fù)數(shù)結(jié)果也是如此,只不過此時(shí)舍入為負(fù)無窮,也就是說符號域?yàn)?1 的無窮。有了 NaN 的經(jīng)驗(yàn)我們不難理解,特殊值無窮使得計(jì)算中發(fā)生的上溢錯(cuò)誤不必以終止運(yùn)算為結(jié)果。

無窮和除 NaN 以外的其它浮點(diǎn)數(shù)一樣是有序的,從小到大依次為負(fù)無窮,負(fù)的有窮非零值,正負(fù)零(隨后介紹),正的有窮非零值以及正無窮。除 NaN 以外的任何非零值除以零,結(jié)果都將是無窮,而符號則由作為除數(shù)的零的符號決定。

回顧我們對 NaN 的介紹,當(dāng)零除以零時(shí)得到的結(jié)果不是無窮而是 NaN 。原因不難理解,當(dāng)除數(shù)和被除數(shù)都逼近于零時(shí),其商可能為任何值,所以 IEEE 標(biāo)準(zhǔn)決定此時(shí)用 NaN 作為商比較合適。

4.3. 有符號的零

因?yàn)?IEEE 標(biāo)準(zhǔn)的浮點(diǎn)數(shù)格式中,小數(shù)點(diǎn)左側(cè)的 1 是隱藏的,而零顯然需要尾數(shù)必須是零。所以,零也就無法直接用這種格式表達(dá)而只能特殊處理。

實(shí)際上,零保存為尾數(shù)域?yàn)槿珵?0,指數(shù)域?yàn)?emin?- 1 = -127,也就是說指數(shù)域也全為 0。考慮到符號域的作用,所以存在著兩個(gè)零,即 +0 和 -0。不同于正負(fù)無窮之間是有序的,IEEE 標(biāo)準(zhǔn)規(guī)定正負(fù)零是相等的。

零有正負(fù)之分,的確非常容易讓人困惑。這一點(diǎn)是基于數(shù)值分析的多種考慮,經(jīng)利弊權(quán)衡后形成的結(jié)果。有符號的零可以避免運(yùn)算中,特別是涉及無窮的運(yùn)算中,符號信息的丟失。舉例而言,如果零無符號,則等式 1/(1/x) = x 當(dāng)x = ±∞ 時(shí)不再成立。原因是如果零無符號,1 和正負(fù)無窮的比值為同一個(gè)零,然后 1 與 0 的比值為正無窮,符號沒有了。解決這個(gè)問題,除非無窮也沒有符號。但是無窮的符號表達(dá)了上溢發(fā)生在數(shù)軸的哪一側(cè),這個(gè)信息顯然是不能不要的。零有符號也造成了其它問題,比如當(dāng) x=y 時(shí),等式1/x = 1/y 在 x 和 y 分別為 +0 和 -0 時(shí),兩端分別為正無窮和負(fù)無窮而不再成立。當(dāng)然,解決這個(gè)問題的另一個(gè)思路是和無窮一樣,規(guī)定零也是有序的。但是,如果零是有序的,則即使?if (x==0)?這樣簡單的判斷也由于 x 可能是 ±0 而變得不確定了。兩害取其輕者,零還是無序的好。

4.4. 非規(guī)范化數(shù)

我們來考察浮點(diǎn)數(shù)的一個(gè)特殊情況。選擇兩個(gè)絕對值極小的浮點(diǎn)數(shù),以單精度的二進(jìn)制浮點(diǎn)數(shù)為例,比如 1.001 × 2-125?和 1.0001 × 2-125?這兩個(gè)數(shù)(分別對應(yīng)于十進(jìn)制的 2.6448623 × 10-38?和 2.4979255 × 10-38)。顯然,他們都是普通的浮點(diǎn)數(shù)(指數(shù)為 -125,大于允許的最小值 -126;尾數(shù)更沒問題),按照 IEEE 754 可以分別保存為 00000001000100000000000000000000(0x1100000)和 00000001000010000000000000000000(0x1080000)。

現(xiàn)在我們看看這兩個(gè)浮點(diǎn)數(shù)的差值。不難得出,該差值為 0.0001 × 2-125,表達(dá)為規(guī)范浮點(diǎn)數(shù)則為 1.0 × 2-129。問題在于其指數(shù)大于允許的最小指數(shù)值,所以無法保存為規(guī)范浮點(diǎn)數(shù)。最終,只能近似為零(Flush to Zero)。這中特殊情況意味著下面本來十分可靠的代碼也可能出現(xiàn)問題:

if (x != y) {z = 1 / (x -y); }

正如我們精心選擇的兩個(gè)浮點(diǎn)數(shù)展現(xiàn)的問題一樣,即使 x 不等于 y,x 和 y 的差值仍然可能絕對值過小,而近似為零,導(dǎo)致除以 0 的情況發(fā)生。

為了解決此類問題,IEEE 標(biāo)準(zhǔn)中引入了非規(guī)范(Denormalized)浮點(diǎn)數(shù)。規(guī)定當(dāng)浮點(diǎn)數(shù)的指數(shù)為允許的最小指數(shù)值,即?emin?時(shí),尾數(shù)不必是規(guī)范化的。比如上面例子中的差值可以表達(dá)為非規(guī)范的浮點(diǎn)數(shù) 0.001 × 2-126,其中指數(shù) -126 等于?emin。注意,這里規(guī)定的是"不必",這也就意味著"可以"。當(dāng)浮點(diǎn)數(shù)實(shí)際的指數(shù)為?emin,且指數(shù)域也為?emin?時(shí),該浮點(diǎn)數(shù)仍是規(guī)范的,也就是說,保存時(shí)隱含著一個(gè)隱藏的尾數(shù)位。為了保存非規(guī)范浮點(diǎn)數(shù),IEEE 標(biāo)準(zhǔn)采用了類似處理特殊值零時(shí)所采用的辦法,即用特殊的指數(shù)域值?emin?- 1 加以標(biāo)記,當(dāng)然,此時(shí)的尾數(shù)域不能為零。這樣,例子中的差值可以保存為 00000000000100000000000000000000(0x100000),沒有隱含的尾數(shù)位。

有了非規(guī)范浮點(diǎn)數(shù),去掉了隱含的尾數(shù)位的制約,可以保存絕對值更小的浮點(diǎn)數(shù)。而且,也由于不再受到隱含尾數(shù)域的制約,上述關(guān)于極小差值的問題也不存在了,因?yàn)樗锌梢员4娴母↑c(diǎn)數(shù)之間的差值同樣可以保存。

總結(jié)

以上是生活随笔為你收集整理的关于浮点数的原理详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 97se.com| www.中文字幕 | 又爽又黄视频 | 少妇又白又嫩又色又粗 | 污污在线观看视频 | 99这里| 欧美青青草 | 91视频最新 | 日韩福利片 | 男生舔女生的屁股 | 91在线成人| 欧美精品 在线观看 | 欧美精品v国产精品v日韩精品 | 337p粉嫩色噜噜噜大肥臀 | 国产午夜麻豆影院在线观看 | 国产精品人妻 | 欧美亚洲视频在线观看 | 91久久视频 | 野外一级片 | 欧美交换国产一区内射 | 人人妻人人藻人人爽欧美一区 | 中国久久久| 国产精品伦理 | 欧美狠狠爱 | 国产成人啪免费观看软件 | 国产精品美女自拍视频 | 小柔好湿好紧太爽了国产网址 | 亚洲色图第三页 | 欧美男人的天堂 | 69影院少妇在线观看 | 精品一区二区三区无码按摩 | 黑人操日本女人视频 | 国产深夜视频 | 日日草天天干 | www.久久爱 | www.在线观看视频 | 性少妇mdms丰满hdfilm | 午夜福利理论片在线观看 | 色呦呦网站入口 | 黄色av电影网站 | www成人在线观看 | 日本视频免费在线播放 | 好妞色妞国产在线视频 | aa成人| 深夜福利免费视频 | 日韩国产精品久久 | 欧美粗又大 | 中文字幕999 | 日本一区二区三区在线观看视频 | 亚洲h | 风韵少妇性饥渴推油按摩视频 | 麻豆国产网站 | 精品久久久久久久无码 | 五月天激情丁香 | 日韩精品一卡 | 刘玥91精选国产在线观看 | 在线观看免费高清视频 | 亚洲国产精品久久久久久久 | 日本人妻不卡一区二区三区中文字幕 | 亚洲精品无码一区二区 | 中文字母av| 国产免费av一区二区 | xx色综合 | 91亚洲一区二区三区 | 成年人视频在线观看免费 | 一区二区视频在线播放 | 国产秋霞| 奇米在线播放 | 国产激情毛片 | 天天插插 | 97视频久久久| 狂野欧美性猛交xxxxhd | 成人在线不卡视频 | 美女被啪羞羞粉色视频 | av一卡二卡| 午夜性福利视频 | 久久久99国产精品免费 | 成人片在线看 | 日本三级韩国三级三级a级按摩 | 老司机在线精品视频 | 国产专区第一页 | 国产91精品ai换脸 | 日本打白嫩屁股视频 | 美人被强行糟蹋np各种play | 免费成人深夜 | 国产又黄又爽视频 | av中出在线 | 亚洲免费成人 | 黄色av电影在线观看 | 四虎影酷 | 97精品人妻麻豆一区二区 | 日韩美女一区 | 老鸭窝av在线 | 高h在线观看 | 丁香婷婷色| 亚洲日本国产精品 | 欧美日韩一区二区三区四区五区 | 久久精品免费一区二区 | 欧美黄色三级视频 |