C++ 一個2^20 /5 floor函數的有趣問題 |
答題得分者是:Coffee
|
juneo
高階會員 發表:103 回覆:190 積分:118 註冊:2004-05-13 發送簡訊給我 |
如標題所述 我是使用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 /> |
herbert2
尊榮會員 發表:58 回覆:640 積分:894 註冊:2004-04-16 發送簡訊給我 |
您若用 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 是否有計算上的錯誤? 跟大家討論一下,如果有知道的先進歡迎解題. |
2007
中階會員 發表:54 回覆:90 積分:98 註冊:2008-08-12 發送簡訊給我 |
大大:
你先不要用 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 發送簡訊給我 |
發文請注重分區。
這個問題應該不是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 發送簡訊給我 |
是阿,不過精度的問題,通常只有本科系的會知道,半路出家的,通常不清楚
精度,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 發送簡訊給我 |
感謝幾位大大解惑.
但是我想再請教各位在精準度上 單精確度(float,32位元)、雙精確度(double,64位元)的問題. 理論上我使用的是"雙精準度",那麼我應該比float更精準,為何還是會有0.2的誤差值問題? 另外,如果是精準度問題,相差在小數一位的範圍好像不是很合理,畢竟我使用的是64bit的精準度, 是否floor函數在轉換上產生精準度的差異? 是阿,不過精度的問題,通常只有本科系的會知道,半路出家的,通常不清楚 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 看得懂得就看,看不懂的,就...看著辦吧!呵呵! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 我很感謝大大提供更多的知識,但是我還是介意那些"語氣用詞" 古有云: 聞道有先後,術業有專攻,建議盡量勿以此態度對人,共勉之!! 勿讓問題的表象影響您深睿的智慧. 標題我想修改,但是我的IE好像無法在度開啟編輯視窗. 原因可能是我加入程式碼的那段語法有問題. |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
很抱歉,讓你感到不快
但我就是這樣,而且,「語氣」應該是當下「聽到」,並配合當下狀況,才能加以解釋 網路,應該是只有文字上的意思,你要解釋到負面的說法,哪我也沒輒 (一樣言詞,萬種解法) 我就是半路出家的,我也就是看著該說明解釋,照著上面說明辦 所以你不滿,那我閉嘴就是,別壞了你的好心情 凡是應往光明面看 ===================引 用 juneo 文 章=================== 是阿,不過精度的問題,通常只有本科系的會知道,半路出家的,通常不清楚 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 看得懂得就看,看不懂的,就...看著辦吧!呵呵! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 我很感謝大大提供更多的知識,但是我還是介意那些"語氣用詞" 古有云: 聞道有先後,術業有專攻,建議盡量勿以此態度對人,共勉之!! 勿讓問題的表象影響您深睿的智慧. |
juneo
高階會員 發表:103 回覆:190 積分:118 註冊:2004-05-13 發送簡訊給我 |
|
Coffee
版主 發表:31 回覆:878 積分:561 註冊:2006-11-15 發送簡訊給我 |
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好像無法在度開啟編輯視窗. 原因可能是我加入程式碼的那段語法有問題.
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。 為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。 在引述到我的文時自然會儘量替各位想辦法,謝謝大家! |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |