在實(shí)際編程中,經(jīng)常會(huì)用到浮點(diǎn)運(yùn)算,,大家可能會(huì)發(fā)現(xiàn)其結(jié)果出現(xiàn)誤差,,與實(shí)際期待值不一樣。如下C#代碼: float a = 0.65f; float b = 0.6f; float c = a - b; 此時(shí)c為多少,? 0.05?錯(cuò)誤,! 此時(shí)c為0.0499999523,! 為什么,? 其根本原因是計(jì)算機(jī)所使用二進(jìn)制01代碼無(wú)法準(zhǔn)確表示某些帶小數(shù)位的十進(jìn)制數(shù)據(jù),。 下面我們來(lái)分析下: 我們知道將一個(gè)十進(jìn)制數(shù)值轉(zhuǎn)換為二進(jìn)制數(shù)值,,需要通過(guò)下面的計(jì)算方法: 1. 整數(shù)部分:連續(xù)用該整數(shù)除以2,取余數(shù),,然后商再除以2,,直到商等于0為止。然后把得到的各個(gè)余數(shù)按相反的順序排列,。簡(jiǎn)稱(chēng)"除2取余法"。 2. 小數(shù)部分:十進(jìn)制小數(shù)轉(zhuǎn)換為二進(jìn)制小數(shù),,采用"乘2取整,,順序排列"法,。用2乘以十進(jìn)制小數(shù),將得到的整數(shù)部分取出,,再用2乘余下的小數(shù)部分,,然后再將積的整數(shù)部分取出,,如此進(jìn)行,直到積中的小數(shù)部分為0或者達(dá)到所要求的精度為止,。然后把取出的整數(shù)部分按順序排列起來(lái),,即先取出的整數(shù)部分作為二進(jìn)制小數(shù)的高位,后取出的整數(shù)部分作為低位有效位,。簡(jiǎn)稱(chēng)"乘2取整法"。 3. 含有小數(shù)的十進(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制,,整數(shù)、小數(shù)部分分別進(jìn)行轉(zhuǎn)換,,然后相加。 例如:將十進(jìn)制數(shù)值25.75轉(zhuǎn)換為二進(jìn)制數(shù)值,,步驟如下: 25(整數(shù)部分) 25/2=12......1 12/2=6.......0 6/2=3......0 3/2=1......1 1/2=0......1 (25) 10=(11001) 2 0.75(小數(shù)部分) 0.75*2=1.5......1 0.5*2=1......1 (0.75) 10=(0.11) 2 (25.75) 10=(11001) 2+(0.11) 2=(11001.11) 2 按照上述方法,,我們將0.65及0.6轉(zhuǎn)換為二進(jìn)制代碼: (0.65)10 =
(0.101001100110011001100110011001100110011......)2 (0.6) 10 =
(0.10011001100110011001100110011001100110011......)2 后面的省略號(hào)表示已經(jīng)算不完了,,后面在無(wú)限重復(fù) 0011 這段二進(jìn)制數(shù)值。 文章開(kāi)始部分,,我們用的float類(lèi)型,,下面我們來(lái)看看float類(lèi)型是否能存儲(chǔ)上面轉(zhuǎn)換出的二進(jìn)制代碼。 目前計(jì)算機(jī)上存儲(chǔ)浮點(diǎn)數(shù)值是按照IEEE(電氣和電子工程師協(xié)會(huì))754浮點(diǎn)存儲(chǔ)格式標(biāo)準(zhǔn)來(lái)存儲(chǔ)的,。 IEEE單精度浮點(diǎn)格式共32位,,包含三個(gè)構(gòu)成字段:23位小數(shù)f,,8位偏置指數(shù)e,1位符號(hào)s,。將這些字段連續(xù)存放在一個(gè)32位字里,,并對(duì)其進(jìn)行編碼,。其中0:22位包含23位的小數(shù)f; 23:30位包含8位指數(shù)e,;第31位包含符號(hào)s。如下圖所示: 也就是說(shuō)上面將0.65及0.5轉(zhuǎn)換出的二進(jìn)制代碼,,我們只能存儲(chǔ)23位,,即使數(shù)據(jù)類(lèi)型為double,也只能存儲(chǔ)52位,,這樣大家便能看出問(wèn)題出現(xiàn)的原因了,。 截取的二進(jìn)制代碼已無(wú)法正確表示0.65及0.5,根據(jù)這個(gè)二進(jìn)制代碼肯定無(wú)法正確得到結(jié)果0.05,。 C語(yǔ)言浮點(diǎn)型變量 小數(shù)點(diǎn)后面有效數(shù)字的位數(shù) 浮點(diǎn)型變量分為單精度(float型),、雙精度(double型)、長(zhǎng)雙精度(long double型)3類(lèi),,單精度浮點(diǎn)型小數(shù)點(diǎn)后面有效數(shù)字為6~7位和雙精度浮點(diǎn)型小數(shù)點(diǎn)后面有效數(shù)字為15~16位 如下面這個(gè)例子 float a; scanf("%f", &a); printf("%f\n", a);
輸入:1.123456789 輸出:1.12345684 //小數(shù)點(diǎn)后面6位才是精確值
********************************************** 原文來(lái)源:http://www./data-structure/v493395.html http://z.baidu.com/question/226808286.html?fr=qrl&cid=203&index=1 |
|
來(lái)自: e3399 > 《CLanguage》