搞不懂的C語言

2009-05-07 4:03 am
在C語言裡有一種將已宣告資料型態的變數強制轉換成
另一資料型態的機制:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
float num1=30000.1f;
float num2=0.0004f;
printf("%f\n",num1+num2);
system("pause");
return 0;
}

將此程式碼用 Dev-c++4.9.9.2 編譯並執行過後,
會得到30000.100009

這時我知道是因為float的精準度只有7~8位
所以我把printf("%f\n",num1+num2);
改成 printf("%f\n",(double)num1+num2);

這時資料型態應該已經改成 double 的型態了
但是怎麼執行出來的數字還是沒變

有高手可以告訴我嗎??

P.S : 就算把 %f 改成 %lf 也是一樣沒變 ˊˋ

回答 (2)

2009-05-07 5:01 am
✔ 最佳答案
0. 你的 P.S. 沒用的原因,在 Promotion!
 簡言之,printf 的 float 引數永遠會自動被轉成 double!
 參 http://tw.knowledge.yahoo.com/question/question?qid=1508080209097 及其中的 link
1. 那你這題的原因是?
 float num1 = 30000.1f;
 printf("%16.10f + %23.21f = %17.12f\n", num1, num2, num1 + num2);
 30000.0996093750 + 0.000399999989895150070 = 30000.100009374990
 看懂了?
 因為,
  num1 本來就不是 30000.1! 在存成 float 時,它就不準了!
  num2 也不是 .0004!
 因此,任你再怎麼轉成更準的數,它存入 num_時,就已不準!
 怎麼轉也沒用!
哪不懂請再問! ^_^

2009-05-06 21:07:23 補充:
也就是說:它是浮點數的問題,不是 C 的問題!

寫成下面那樣會較好看
 30000.099609375
+    0.00039999998989515007
=30000.10000937499

2009-05-07 06:58:12 補充:
To bean_bottom_2:

就算那本經典沒這麼寫,實做上,也辦不到吧!?
所以,仍是 浮點數 的問題,不是 C 的問題。

難道,(比如說) MatLab 做得到?

我 MatLab 只會點皮毛。
就我會的範圍,要把 double 〝數值〞轉成 Symbolic Calculation,
一樣仍然是原準度,不會變更準!

2009-05-07 21:27:14 補充:
Promotion 是你看了那 link 還不懂嗎?

30000.0996093750 當你只印 7.22 位時,它是
30000.0996... 必須進位成
30000.10_
所以,它有 7.22 位的準度沒錯!
但,不表示第 7.23位起,都是 0!

小數部份,必須是 2^-n 的和,才會沒有誤差!
0.0004不能用 2^-n 的和湊出來!
所以,就不準了!
但,它仍準到 7.22 位!
0.0003999999'89895'150070 注意 ' ' 中的數!能不進位嗎?

2009-05-07 21:27:44 補充:
你要他(一次運算還會)準,(總)位數一定要夠。
30000.1004 是 9 位數,double 有 15位以上,
一次運算,double 還罩得住!

另一個方法,就是:自己寫大數!
大整數只是大數的一小支。

還有個方法,寫 Symbolic Calculation!

2009-05-08 08:50:56 補充:
I do NOT say it does NOT write like that!

I say "EVEN IF" (就算) it does not, the problem, in fact, will still exist.

2009-05-08 08:56:17 補充:
This means two things. First, it states like that. Second, The problem should not caused by that statement.

Maybe your opinion means differetly like the following:

2009-05-08 08:56:30 補充:
If the book states C compiler should try to solve this problem, you should not have this problem now because C will have build-in Symbolic Calculation. But, sorry, the book write like this. So, you must accept this fact that converting to a more precise type can not solve the precision problem.

2009-05-08 08:59:08 補充:
Then, we are talking about the same thing, right?

Simple sentences make confusing frequently.

Sorry if I misunderstand that you mean "The reason is caused by that statement, not the float itself. The compiler should have to solve this problem if the book does not say that!"
2009-05-07 8:15 am
From "The C Programming Language":
When a less precise floating value is converted to an equally or more precise floating type, the value is unchanged.

2009-05-08 06:51:37 補充:
To Jacob:
For the record, the book "The C Programming Language" does have the statement I copied here. Page 198 Floating type Section A6.4 second edition.


收錄日期: 2021-05-02 00:01:27
原文連結 [永久失效]:
https://hk.answers.yahoo.com/question/index?qid=20090506000015KK08458

檢視 Wayback Machine 備份