全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3451
推到 Plurk!
推到 Facebook!

C++ 一個2^20 /5 floor函數的有趣問題

答題得分者是:Coffee
juneo
高階會員


發表:103
回覆:190
積分:118
註冊:2004-05-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-11-13 23:16:37 IP:220.138.xxx.xxx 訂閱
如標題所述 我是使用floor function
當輸入2^20 = 1048576
然後 1048576 /5 用If判斷是否整除?
結果出現整除數字(209715.00),但卻判斷兩個數字不同的情況
但是用excel 計算 卻得到 209715.2
所以產生在C 中 math.h floor function 是否有計算上的錯誤?
跟大家討論一下,如果有知道的先進歡迎解題.

以下是程式碼

<textarea> long double quotient,dividend,a;
dividend = StrToFloat(Edit1->Text);
a = StrToFloat(Edit2->Text);
quotient = dividend / a;
quotient = floor(quotient);
if(quotient == (dividend / a))
{
Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("ture");
}else{
Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("false");
}

</textarea><br />
編輯記錄
juneo 重新編輯於 2008-11-13 23:18:17, 註解 無‧
juneo 重新編輯於 2008-11-13 23:20:19, 註解 無‧
juneo 重新編輯於 2008-11-13 23:22:08, 註解 無‧
herbert2
尊榮會員


發表:58
回覆:640
積分:894
註冊:2004-04-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-11-14 00:41:25 IP:211.72.xxx.xxx 訂閱
您若用 BCB5, 一定有問題.
int ixA = 1.4 * 5; // 得 6 (但 BCB4, BCB6 得 7)
double nxB = 1.4 * 5; // 得 6.9999......
ixA = nxB; // 得 7

int ixQA;
quotient = dividend / a;
ixQA = floor(quotient 0.00002);
然後才比較 if (double(ixQA) == quotient) 則應可正常.

通常 double 比較 == 常有問題,
故小弟常將兩者用 int((d1 0.00002) * 10000.0) == int((d2 0.00002) * 10000.0) 做比較

===================引 用 juneo 文 章===================
如標題所述 我是使用floor function
當輸入2^20 = 1048576
然後 1048576 /5 用If判斷是否整除?
結果出現整除數字(209715.00),但卻判斷兩個數字不同的情況
但是用excel 計算 卻得到 209715.2
所以產生在C 中 math.h floor function 是否有計算上的錯誤?
跟大家討論一下,如果有知道的先進歡迎解題.
編輯記錄
herbert2 重新編輯於 2008-11-14 00:42:38, 註解 無‧
herbert2 重新編輯於 2008-11-14 01:06:18, 註解 無‧
2007
中階會員


發表:54
回覆:90
積分:98
註冊:2008-08-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-11-14 08:34:28 IP:220.132.xxx.xxx 未訂閱
大大:

你先不要用 FloatToStrF,直接用 FloatToStr,就知道它的值是不同的,1048576 /5 = 209715.2 floor(209715.2) = 209715
因為我沒用過 FloatToStrF,所以不知是不是它的問題,還是我們不會用。

Label6->Caption = FloatToStr((dividend / a));
Label7->Caption = FloatToStr(floor(dividend / a));
//Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
//Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);



[code cpp]
long double quotient,dividend,a;
dividend = StrToFloat(Edit1->Text);
a = StrToFloat(Edit2->Text);
quotient = dividend / a;
quotient = floor(quotient);
if(quotient == (dividend / a))
{
Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("ture");
}else{
Label6->Caption = FloatToStr((dividend / a));
Label7->Caption = FloatToStr(floor(dividend / a));

//Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
//Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("false");
}
[/code]



===================引 用 juneo 文 章===================
如標題所述 我是使用floor function
當輸入2^20 = 1048576
然後 1048576 /5 用If判斷是否整除?
結果出現整除數字(209715.00),但卻判斷兩個數字不同的情況
但是用excel 計算 卻得到 209715.2
所以產生在C 中 math.h floor function 是否有計算上的錯誤?
跟大家討論一下,如果有知道的先進歡迎解題.

以下是程式碼

<textarea> long double quotient,dividend,a;
dividend = StrToFloat(Edit1->Text);
a = StrToFloat(Edit2->Text);
quotient = dividend / a;
quotient = floor(quotient);
if(quotient == (dividend / a))
{
Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("ture");
}else{
Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("false");
}

</textarea><br />
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-11-14 09:02:10 IP:61.230.xxx.xxx 訂閱
發文請注重分區。

這個問題應該不是floor錯誤造成的,而是浮點數本身的表示方式就有精度的限制,浮點數多數是以IEEE754的方式儲存。
如果不想受到這一類困擾,換成整數、使用定精度變數,或避開可能出現浮點數的計算方式。
===================引 用 juneo 文 章===================
如標題所述 我是使用floor function
當輸入2^20 = 1048576
然後 1048576 /5 用If判斷是否整除?
結果出現整除數字(209715.00),但卻判斷兩個數字不同的情況
但是用excel 計算 卻得到 209715.2
所以產生在C 中 math.h floor function 是否有計算上的錯誤?
跟大家討論一下,如果有知道的先進歡迎解題.

以下是程式碼

<textarea> long double quotient,dividend,a;
dividend = StrToFloat(Edit1->Text);
a = StrToFloat(Edit2->Text);
quotient = dividend / a;
quotient = floor(quotient);
if(quotient == (dividend / a))
{
Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("ture");
}else{
Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("false");
}

</textarea><br />
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-11-14 09:40:47 IP:59.125.xxx.xxx 訂閱
是阿,不過精度的問題,通常只有本科系的會知道,半路出家的,通常不清楚

精度,http://zh.wikipedia.org/w/index.php?title=IEEE_754&variant=zh-tw

看得懂得就看,看不懂的,就...看著辦吧!呵呵!

===================引 用 Coffee 文 章===================
發文請注重分區。

這個問題應該不是floor錯誤造成的,而是浮點數本身的表示方式就有精度的限制,浮點數多數是以IEEE754的方式儲存。
如果不想受到這一類困擾,換成整數、使用定精度變數,或避開可能出現浮點數的計算方式。
===================引 用 juneo 文 章===================
如標題所述 我是使用floor function
當輸入2^20 = 1048576
然後 1048576 /5 用If判斷是否整除?
結果出現整除數字(209715.00),但卻判斷兩個數字不同的情況
但是用excel 計算 卻得到 209715.2
所以產生在C 中 math.h floor function 是否有計算上的錯誤?
跟大家討論一下,如果有知道的先進歡迎解題.

以下是程式碼

<textarea> long double quotient,dividend,a;
dividend = StrToFloat(Edit1->Text);
a = StrToFloat(Edit2->Text);
quotient = dividend / a;
quotient = floor(quotient);
if(quotient == (dividend / a))
{
Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("ture");
}else{
Label6->Caption = FloatToStrF((dividend / a),ffFixed,6,6);
Label7->Caption = FloatToStrF(floor(dividend / a),ffFixed,6,6);
ShowMessage("false");
}

</textarea><br />
juneo
高階會員


發表:103
回覆:190
積分:118
註冊:2004-05-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-11-14 19:19:58 IP:60.249.xxx.xxx 訂閱
感謝幾位大大解惑.
但是我想再請教各位在精準度上 單精確度(float,32位元)、雙精確度(double,64位元)的問題.
理論上我使用的是"雙精準度",那麼我應該比float更精準,為何還是會有0.2的誤差值問題?
另外,如果是精準度問題,相差在小數一位的範圍好像不是很合理,畢竟我使用的是64bit的精準度,
是否floor函數在轉換上產生精準度的差異?

是阿,不過精度的問題,通常只有本科系的會知道,半路出家的,通常不清楚
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
看得懂得就看,看不懂的,就...看著辦吧!呵呵!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我很感謝大大提供更多的知識,但是我還是介意那些"語氣用詞"
古有云: 聞道有先後,術業有專攻,建議盡量勿以此態度對人,共勉之!!
勿讓問題的表象影響您深睿的智慧.

標題我想修改,但是我的IE好像無法在度開啟編輯視窗.
原因可能是我加入程式碼的那段語法有問題.
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-11-17 10:19:45 IP:59.125.xxx.xxx 訂閱
很抱歉,讓你感到不快

但我就是這樣,而且,「語氣」應該是當下「聽到」,並配合當下狀況,才能加以解釋
網路,應該是只有文字上的意思,你要解釋到負面的說法,哪我也沒輒 (一樣言詞,萬種解法)

我就是半路出家的,我也就是看著該說明解釋,照著上面說明辦

所以你不滿,那我閉嘴就是,別壞了你的好心情

凡是應往光明面看

===================引 用 juneo 文 章===================

是阿,不過精度的問題,通常只有本科系的會知道,半路出家的,通常不清楚
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
看得懂得就看,看不懂的,就...看著辦吧!呵呵!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我很感謝大大提供更多的知識,但是我還是介意那些"語氣用詞"
古有云: 聞道有先後,術業有專攻,建議盡量勿以此態度對人,共勉之!!
勿讓問題的表象影響您深睿的智慧.

juneo
高階會員


發表:103
回覆:190
積分:118
註冊:2004-05-13

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-11-17 12:12:01 IP:140.114.xxx.xxx 訂閱
syntax 大大,我也很抱歉提出這樣的"問題"
我覺得這邊是可以"討論問題"的地方
無論問題簡單與困難 ^^

我覺得我以後會更加強"尊重提問者"與"尊重回應者"的部分
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-11-17 13:21:39 IP:59.124.xxx.xxx 訂閱
floor本身轉換依舊沒有問題,問題在於你將floor拋出來的int又丟回給double,
這時候你期望double var裡面存的是小數全為0的值,很可惜並不是。
因此你拿兩個你認為小數應該全為0的值比較會相等,實際上這兩個值因為都是double,所以不會保證小數全為0。
floor本來就只取整數,不存在四捨五入,五捨六入的問題,就算是0.9一樣會被捨掉。

雖然我是本科系,不過實際上我在大學前就開始有玩一點了,
早期compiler語言的書基本上都會在operator章節提示equvialent不可直接比較浮點數,因為會有誤差。
通常也會提盡量不要把boolean值直接換成int 使用,會降低可移值性,而compiler本身也不保證隨版本演進或進行最佳化時,boolean表示不會被更動。

我試了一下確實那個script造成修改問題。
以後發文請利用內建的語法來表示程式碼,並請自行避開可能會造成forbidden的javascript保留字,如半形的script等字眼。
===================引 用 juneo 文 章===================
感謝幾位大大解惑.
但是我想再請教各位在精準度上 單精確度(float,32位元)、雙精確度(double,64位元)的問題.
理論上我使用的是"雙精準度",那麼我應該比float更精準,為何還是會有0.2的誤差值問題?
另外,如果是精準度問題,相差在小數一位的範圍好像不是很合理,畢竟我使用的是64bit的精準度,
是否floor函數在轉換上產生精準度的差異?

是阿,不過精度的問題,通常只有本科系的會知道,半路出家的,通常不清楚
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
看得懂得就看,看不懂的,就...看著辦吧!呵呵!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我很感謝大大提供更多的知識,但是我還是介意那些"語氣用詞"
古有云: 聞道有先後,術業有專攻,建議盡量勿以此態度對人,共勉之!!
勿讓問題的表象影響您深睿的智慧.

標題我想修改,但是我的IE好像無法在度開啟編輯視窗.
原因可能是我加入程式碼的那段語法有問題.
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
系統時間:2024-04-20 1:19:25
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!