RSS   



  可打印版本 | 推薦給朋友 | 訂閱主題 | 收藏主題 | 純文字版  


 


 
主題: [C&C++] [問題]關於c的浮點數   字型大小:||| 
XYZ007
銀驢友〔高級〕
等級: 14等級: 14等級: 14等級: 14


十週年紀念徽章(四級)  

今日心情

 . 積分: 1065
 . 文章: 9458
 . 收花: 6399 支
 . 送花: 705 支
 . 比例: 0.11
 . 在線: 2024 小時
 . 瀏覽: 48470 頁
 . 註冊: 7207
 . 失蹤: 532
 . Taiwan
#1 : 2011-2-16 07:08 PM     只看本作者 引言回覆

我看的書(C Primer Plus 5/e)中提到:
    在標準的c語言中,float至少可表示六個有效數字(significant figure),且數字範圍至少為10^(-37) 到10^37 。第一個規定六個有效數字的意思是--例如,以float型態表示33.333333這個數字時,至少前六位數字是正確的;而第二個規定有效範圍的意思則是方便用來表示太陽的質量(2.0e30公斤)、質子的電荷(1.6e-19庫侖)或是國債…等等這類的數值。
(中間略過)
    此外,c還提供了double浮點數型態。double的數字範圍跟float一樣,不過其有效數字至少可達10個數字,…(以下略過)
    c允許第三種浮點數型態:long double,其目的是為了增加精確度,不過c只保證long double至少和double一樣的精準。

另外一本(visual c++6教學範本)則說float為7位有效位數,double為15位。

兩本寫的不太一樣,該聽哪一本的?
想問的是,這個有效數字是怎麼看,像33.333333是前六個也就是33.3333至少是正確的嗎?
有效數字和數字範圍差別在哪?數字範圍是指可以顯示出來的是10^(-37) 到10^37,在這之間的值有可能是不正確的?
還請大大指教一下,謝謝



[如果你喜歡本文章,就按本文章之鮮花~送花給作者吧,你的支持就是別人的動力來源]
本文連接  
檢閱個人資料  發私人訊息  Blog  快速回覆 新增/修改 爬文標記
cld
銀驢友〔中級〕
等級: 13等級: 13等級: 13等級: 13


十週年紀念徽章(六級)  

 . 積分: 560
 . 文章: 837
 . 收花: 5039 支
 . 送花: 5967 支
 . 比例: 1.18
 . 在線: 4584 小時
 . 瀏覽: 22770 頁
 . 註冊: 6888
 . 失蹤: 107
#2 : 2011-2-16 08:09 PM     只看本作者 引言回覆

從基本的C來說 (非c++)

float 有 6個有效位數(小數點以後),範圍為 10^(-38) ~ 10^(38)
----------------------------------------------
  (+-1.175494E-38 ~ +-3.402823E+38)
有效位數為小數點後之數字 ,而數質範圍如 () 內之範圍
----------------------------------------------


double 有 15個有效位數(小數點以後),範圍為 10^(-308) ~ 10^(308)

基本上通則是如此

但電腦儲存資料是以二進制處理
故實際數值範圍並非整數
而不同之電腦系統因硬體不同
軟體也可能會為之修正
實際結果
以所使用之 C編譯器而定



[如果你喜歡本文章,就按本文章之鮮花~送花給作者吧,你的支持就是別人的動力來源]
本文連接  
檢閱個人資料  發私人訊息  Blog  快速回覆 新增/修改 爬文標記
XYZ007
銀驢友〔高級〕
等級: 14等級: 14等級: 14等級: 14


十週年紀念徽章(四級)  

今日心情

 . 積分: 1065
 . 文章: 9458
 . 收花: 6399 支
 . 送花: 705 支
 . 比例: 0.11
 . 在線: 2024 小時
 . 瀏覽: 48470 頁
 . 註冊: 7207
 . 失蹤: 532
 . Taiwan
#3 : 2011-2-16 09:47 PM     只看本作者 引言回覆

那假如double有15個有效位數,308-15=293
那意思是有293個不精確的小數?



[如果你喜歡本文章,就按本文章之鮮花~送花給作者吧,你的支持就是別人的動力來源]
本文連接  
檢閱個人資料  發私人訊息  Blog  快速回覆 新增/修改 爬文標記
cld
銀驢友〔中級〕
等級: 13等級: 13等級: 13等級: 13


十週年紀念徽章(六級)  

 . 積分: 560
 . 文章: 837
 . 收花: 5039 支
 . 送花: 5967 支
 . 比例: 1.18
 . 在線: 4584 小時
 . 瀏覽: 22770 頁
 . 註冊: 6888
 . 失蹤: 107
#4 : 2011-2-16 10:01 PM     只看本作者 引言回覆

308 指的是 10^308 次方
因為實際放有效值的只有 8 byte
故實際有效的數值是 (2^64)/2
有效位數大約是15位(超過的部分會被忽略,處理模式由C編譯器決定)
多餘的部分是由 次方部分所涵蓋
而非 308-15 的狀態

[cld 在  2011-2-16 10:09 PM 作了最後編輯]



[如果你喜歡本文章,就按本文章之鮮花~送花給作者吧,你的支持就是別人的動力來源]
本文連接  
檢閱個人資料  發私人訊息  Blog  快速回覆 新增/修改 爬文標記
ericshliao
銀驢友〔高級〕
等級: 14等級: 14等級: 14等級: 14


今日心情

 . 積分: 849
 . 精華: 2
 . 文章: 1589
 . 收花: 7188 支
 . 送花: 5723 支
 . 比例: 0.8
 . 在線: 5412 小時
 . 瀏覽: 20831 頁
 . 註冊: 6742
 . 失蹤: 3244
#5 : 2011-3-19 05:56 PM     只看本作者 引言回覆

照我看起來,兩個寫的沒衝突。
VC++只適用在MS的平台上,而C Primer Plus則是泛指各個implementation,所以後者寫的比較概括,而前者可以寫的很確定。如果樓主是用MS的OS,那當然聽MS的,如果不是,那就看各個平台了。
不過,我得承認,我寫的程式從來沒去仔細留意數值的精準度到幾個位數。



[如果你喜歡本文章,就按本文章之鮮花~送花給作者吧,你的支持就是別人的動力來源]
本文連接  
檢閱個人資料  發私人訊息  Blog  快速回覆 新增/修改 爬文標記
julius
驢有所悟
等級: 3等級: 3
jh71

 . 積分: 18
 . 文章: 18
 . 收花: 140 支
 . 送花: 155 支
 . 比例: 1.11
 . 在線: 151 小時
 . 瀏覽: 3920 頁
 . 註冊: 6315
 . 失蹤: 852
#6 : 2011-3-21 10:34 PM     只看本作者 引言回覆

有點離題,
不過, 還是推薦一份 1991 年 David Goldberg 發表關於 "浮點運算" 小有名氣的文章,

文章名稱 : "What Every Computer Scientist Should Know About Floating-Point Arithmetic"
http://download.oracle.com/docs/ ... 3/ncg_goldberg.html

關於浮點運算的網站,
http://floating-point-gui.de/



[如果你喜歡本文章,就按本文章之鮮花~送花給作者吧,你的支持就是別人的動力來源]
本文連接  
檢閱個人資料  發私人訊息  Blog  快速回覆 新增/修改 爬文標記
ChocoMocha
鐵驢友〔初級〕
等級: 4


 . 積分: 25
 . 文章: 64
 . 收花: 167 支
 . 送花: 677 支
 . 比例: 4.05
 . 在線: 2020 小時
 . 瀏覽: 5920 頁
 . 註冊: 7207
 . 失蹤: 0
#7 : 2011-3-22 05:35 PM     只看本作者 引言回覆

float = (+/-) 1. m X 2^ (e)
1 bit ......... Sign
8 bits......... 次方
23 bits....... 小數

2^(23) = 8388608 => 七個位數...

所以...假設你有兩個float A and B...
A = 0.1111111
B = 0.00000000000000001
A + B = 0.11111110000000001
但是float只有大概七個位數的準確度...所以 A+B 會只剩 0.1111111
也就是說...如果要對兩個相差超過七位數以上的數作加減乘除...就很有可能會掉一些精準值...
大部分的軟體計算都不需要這麼精確...除非你在算的是錢!!!

p.s. A 跟 B 都是十進制



[如果你喜歡本文章,就按本文章之鮮花~送花給作者吧,你的支持就是別人的動力來源]
本文連接  
檢閱個人資料  發私人訊息  Blog  快速回覆 新增/修改 爬文標記
zxvf
驢有所悟
等級: 3等級: 3


 . 積分: 10
 . 文章: 10
 . 收花: 93 支
 . 送花: 2 支
 . 比例: 0.02
 . 在線: 143 小時
 . 瀏覽: 300 頁
 . 註冊: 6742
 . 失蹤: 220
#8 : 2011-4-14 07:19 PM     只看本作者 引言回覆

關於精準度, 可由「定點數」應用在小數表示法比較有感覺

舉 int16 的例子來說,
一般認定的範圍是  -32178 (0x8000) ~ 32767 (0x7FFF)
但在意義上, 可以解釋成 -1 ~ +1 , 只要把小數點放在第 15 個 bits, 邏輯上就是 right shift 15 bits
而通常這個變數可能會寫成 Q15 (表示小數點的位置)

依照不同的應用, 你可以調整小數點的位置, 而得到不同數值範圍
但實務上, 小數點的位置在設計程式的時候就決定了, 就不會換了
要換小數點的位置, 當然也可以, 不過就要一些技巧...

而浮點數會記錄小數點的位置, 可以動態調整, 所以表示範圍是動態的
專用名詞是 dynamic range
由於浮點數要盡可能表示有效位數, 所以正規化之後, 第一個 bit 必須為 1
也因為第一個 bit 為 1, 就可以省去

回到精準度的部分, 不管浮點數 or 定點數
若有一個值是
0.11001b (二進位)
則其 10 進位的值是
0 +
1 x 1/2 +
1 x 1/4 +
0 x 1/8 +
0 x 1/16 +
1 x 1/32
= 0.78125

所以, 要以 10 進位來說精準度有幾個位數, 個人覺得很難理解
以 2 進位來說, 就很容易... 就看有幾個 bits 了



[如果你喜歡本文章,就按本文章之鮮花~送花給作者吧,你的支持就是別人的動力來源]
本文連接  
檢閱個人資料  發私人訊息  Blog  快速回覆 新增/修改 爬文標記

   

快速回覆
表情符號

更多 Smilies

字型大小 : |||      [完成後可按 Ctrl+Enter 發佈]        

溫馨提示:本區開放遊客瀏覽。
選項:
關閉 URL 識別    關閉 表情符號    關閉 Discuz! 代碼    使用個人簽名    接收新回覆信件通知
發表時自動複製內容   [立即複製] (IE only)


 



所在時區為 GMT+8, 現在時間是 2024-3-28 06:24 PM
清除 Cookies - 連絡我們 - TWed2k © 2001-2046 - 純文字版 - 說明
Discuz! 0.1 | Processed in 0.023450 second(s), 6 queries , Qzip disabled