❶ c語言浮點運算感覺很奇怪同樣的數,算出來結果卻不一樣,這是怎麼回事
計算機存儲和運算都是以二進制處理的,而表達式是十進制的,那麼存儲或運算時是要轉換成二進制,計算完成後輸出還要再轉換成十進制。
那麼你應該明白二進制每一位權重都是2^N,此處N為位號,位號分布如下:
...3,2,1,0(小數點) -1,-2,-3...
權重分布如下:
...2^3,2^2,2^1,2^0 (.小數點)2^-1,2^-2,2^-3
例如一個二進制的1.111(B)=1.875(D)
整數部分:1的位號為0,因此1*2^0=1*1=1
小數點向右第一個1:位號為-1,因此1*2^-1=1*1/2=0.5
小數點向右第二個1:位號為-2,因此1*2^-2=1*1/4=0.25
小數點向右第三個1:位號為-3,因此1*2^-3=1*1/4=0.125
合起來1+0.5+0.25+0.125=1.875,其他位依此類推。
無需想得太多,你可以明顯看到,二進制小數表達的數都是不同級別減半後的累加。與十進制的某些小數沒有一一對應,顯然轉換必然會發生誤差。
另一方面,存儲時CPU會對十進制小數會進行編碼,float的尾數長度為23位,階碼8位,符號佔1位,共32位。double是64位,無論如何精度都是有限的,因此也會存在誤差,1.1*100時編譯器會將表達式先轉換二進制並運算運算,運算後再編碼存儲到變數中或臨時變數中,而運算是由CPU直接處理的,因此你可以看到有個0.000002的誤差數,而printf是個函數,對誤差進行了修正。
PS:簡單了解下浮點數的編碼方式網頁鏈接
❷ 關於c語言
浮點數在內存里怎麼可能是這樣存放的。。。。
參考IEEE的浮點數標准。
IEEE制定的浮點數格式
鑒於有人問到在 C 語言中 float 和 double 型態的儲存格式的問題, 所以我就在這邊獻丑一翻, 講講我所了解的部份, 如
有任何錯誤, 請各位大哥多多指教...
IEEE 制定之浮點數格式說明:
float 型態: 用 4 個 bytes 儲存, 也就是 32 bits.
各個 bit 的用途如下:
bit 31 23~30 0~22
┌———┬————┬———————┐
│正負號│ 指數 │ 底數 │
└———┴————┴———————┘
double 型態: 用 8 個 bytes 儲存, 也就是 64 bits.
各個 bit 的用途如下:
bit 63 52~62 0~51
┌———┬————┬———————┐
│正負號│ 指數 │ 底數 │
└———┴————┴———————┘
< 說明 > 正負號 (sign): 1 為負, 0 為正.
指數 (exponential): 將底數乘上 2 的指數次方後就是原來的數.
須注意的是: float 時, 因有 8 bits, 所以能表示的有 2 的
256 次方, 但因為指數應可正可負, 所以 IEEE 規定, 此處算
出的次方須減去 127 才是真的指數,所以 float 的指數可從
-126 到 128.
同理, double 型態有 11 bits, 算出的值須減去 1023, 所以
相關帖子>>>:備下(0字)sinos[5次]2008-7-23 10:12:57IEEE 浮點數格式[詳解](5336字)zzwj5120[23次]2008-7-21 22:03:57IEEE 浮點數格式
IEEE 754 標准規定了三種浮點數格式:單精度、雙精度、擴展精度。《編程卓越之道》第一部的 4.2 節對這些浮點數格式已
進行了詳細的講解,為了讓讀書筆記更像讀書筆記,本文只道出個人的一些理解以及一些疑惑之處。
IEEE 浮點數標準的由來
話說 Intel 計劃給最早的 8086 增加浮點運算單元 (FPU) 時,他們請來了最好的數值分析專家來為 8087 FPU 設計浮點數格
式,這位專家接著又請來了該領域的另外兩位專家,這三個人 (Kahn, coonan 與 Stone) 設計了 Intel 的浮點格式,即
KCS 浮點數標准。這個標准實在太出色了,因此 IEEE 組織將 KCS 選作為 IEEE 浮點數格式的基礎,即 IEEE 標准 754。
單精度浮點數
IEEE 754 標准所定義的單精度浮點數的長度為 32 位,按位域可劃分為:符號位、階碼位與尾數位,如下:
31----------------------22---------------------------------------------------------0
| | |
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
| |-------------------| |----------------------------------------------------------|
符號 階碼 尾數符號位取 0 表示正數,取 1 表示負數。
階碼位是 8 位,這里有一點小門道需要注意,那就是的指數 n 並不能直接當作階碼來處理,需要將其與 127 (0x7f) 相加才
可得到 的階碼表示。
尾數的位域長度在圖示中是 23 位,但實際上卻是 24 位,這個位是「不可見」的,其值固定為 1,這也就是說 IEEE 754 標
准所定義的浮點數,其有效數字是介於 1 與 2 之間的小數。
可以嘗試寫一下 1.0 這個數的二進制單精度浮點格式,這有助於更好地理解單精度浮點數格式的位域分布。
1.0 的二進制單精度浮點格式:0 0111 1111 000 0000 0000 0000 0000 0000值得注意的一個問題是:書上說之所以要將指數
加上 127 來得到階碼,是為了簡化浮點數的比較運算,這一點我沒有體會出來。但是通過 127 這個偏移量 (移碼),可以區
分出指數的正負。階碼為 127 時表示指數為 0;階碼小於 127 時表示負指數;階碼大於 127 時表示正指數。
第二個值得思考的問題是:使用 24 位尾數,大概可以得到 個十進制數字的精度,其中的「半個」數字由 FPU 的好意而產
生的一個隨機數字,這個數字通常接近 5 (四捨五入?)。
第三個問題是我經常要碰到的:IEEE 754 標准所定義的單精度浮點數所表示的數的范圍是多少?書上給出的答案是大約為
或者大約 。這個比較好理解,因為尾數的最大值是接近 2,而指數的范圍是 [-127, 127],那麼這個范圍就可以表示為。
雙精度浮點數
相對於單精度浮點數格式,雙精度的階碼變為 11 位,移碼變為為 1,023,尾數變為 53 位 (包含那個固定為 1 的隱含位)。
這樣,再加上符號位,雙精度浮點數的長度為 64 位,提供了大約 的動態范圍以及 個數字的精度。
擴展精度浮點數
為了追求更高的浮點運算精度,Intel 又搞出來擴展精度格式。擴展精度的浮點數長度為 80 個位,相對於雙精度浮點數所多
出來的 16 個位,有 12 位加入到尾數位中,有 4 位加入到階碼位中。
據說 Intel IA32 架構的的 FPU都是採用擴展精度浮點數進行運算的。當程序調入單、雙精度浮點數時,FPU 將它們轉為擴展
精度,運算結束後再將結果轉成 (四捨五入) 對應的單、雙精度浮點數。
❸ c語言浮點數中的計算問題
浮點數的實現依賴於具體的環境,不同的環境可以有不同的實現特徵。
devc的
我沒有怎麼學習浮點數的實現,只能經驗地說這些了
;還有為方便調試,「%d」可以換成「%f」,那樣編譯器才知道你想要輸出浮點數
❹ c語言浮點型運算錯誤
給定的輸入數據式樣中間有逗號分隔嗎:scanf("%d,%d",&p,&q);
如果是空格分隔就要改為:scanf("%d%d",&p,&q);這樣才行
❺ c語言計算有一些不準確
浮點數就是不精確的,使用浮點數計算得到的結果可能不精確。
❻ 在c語言中,為什麼在一些算數運算中,使用浮點數會損失更多精度
浮點數在計算機中的儲存是不準確的,然而在計算的時候,如果類型轉換為整數的話,小數部分也會丟棄
❼ C語言中浮點類型變數計算誤差
不會吧?你計算的數值是多少?
你輸入的數值是多少啊?