Re: [問題]有關 round() 的問題

看板C_and_CPP (C/C++)作者 (Schottky)時間12年前 (2013/10/03 19:58), 編輯推噓3(305)
留言8則, 5人參與, 最新討論串2/2 (看更多)
※ 引述《watson1988 (watson)》之銘言: : 四捨五入還有其他更簡單的寫法嗎!? 寫了個程式測試... 我們希望標準 ROUND() 的行為應該是: ROUND( 1.49) = 1.000000 ROUND( 1.5) = 2.000000 ROUND( 1.51) = 2.000000 ROUND(-1.49) = -1.000000 ROUND(-1.5) = -2.000000 ROUND(-1.51) = -2.000000 執行結果是 ROUND3 和 ROUND5 這兩種作法才是正解... 我說的 #define ROUND2 floor((x)+0.5) 會造成 ROUND2(-1.5) == -1 這樣也不對, 此外順便炫耀一下華麗的 macro ... :D // URL: http://codepad.org/8gI4wz2b #include <stdio.h> #include <math.h> #define ROUND1(x) ((x)-(int)(x))>=0.5?ceil((x)):floor((x)) #define ROUND2(x) floor((x)+0.5) #define ROUND3(x) (double)(int)((x) + 0.5 - (double)((x) < 0)) #define ROUND4(x) ((x)-floor(x))>=0.5?ceil((x)):floor((x)) #define ROUND5(x) ((x)>0?floor((x)+0.5):ceil((x)-0.5)) #define __T(x) #x #define _T(x) __T(x) #define DEF(y) \ printf("#define " #y "(x) " _T(y(x)) "\n"); \ printf(#y "( 1.49) = % f\n", y(1.49)); \ printf(#y "( 1.5) = % f\n", y(1.5)); \ printf(#y "( 1.51) = % f\n", y(1.51)); \ printf(#y "(-1.49) = % f\n", y(-1.49)); \ printf(#y "(-1.5) = % f\n", y(-1.5)); \ printf(#y "(-1.51) = % f\n", y(-1.51)); \ printf("\n"); int main(void) { DEF(ROUND1); DEF(ROUND2); DEF(ROUND3); DEF(ROUND4); DEF(ROUND5); return 0; } // 執行結果: #define ROUND1(x) ((x)-(int)(x))>=0.5?ceil((x)):floor((x)) ROUND1( 1.49) = 1.000000 ROUND1( 1.5) = 2.000000 ROUND1( 1.51) = 2.000000 ROUND1(-1.49) = -2.000000 ROUND1(-1.5) = -2.000000 ROUND1(-1.51) = -2.000000 #define ROUND2(x) floor((x)+0.5) ROUND2( 1.49) = 1.000000 ROUND2( 1.5) = 2.000000 ROUND2( 1.51) = 2.000000 ROUND2(-1.49) = -1.000000 ROUND2(-1.5) = -1.000000 ROUND2(-1.51) = -2.000000 #define ROUND3(x) (double)(int)((x) + 0.5 - (double)((x) < 0)) ROUND3( 1.49) = 1.000000 ROUND3( 1.5) = 2.000000 ROUND3( 1.51) = 2.000000 ROUND3(-1.49) = -1.000000 ROUND3(-1.5) = -2.000000 ROUND3(-1.51) = -2.000000 #define ROUND4(x) ((x)-floor(x))>=0.5?ceil((x)):floor((x)) ROUND4( 1.49) = 1.000000 ROUND4( 1.5) = 2.000000 ROUND4( 1.51) = 2.000000 ROUND4(-1.49) = -1.000000 ROUND4(-1.5) = -1.000000 ROUND4(-1.51) = -2.000000 #define ROUND5(x) ((x)>0?floor((x)+0.5):ceil((x)-0.5)) ROUND5( 1.49) = 1.000000 ROUND5( 1.5) = 2.000000 ROUND5( 1.51) = 2.000000 ROUND5(-1.49) = -1.000000 ROUND5(-1.5) = -2.000000 ROUND5(-1.51) = -2.000000 ※ 編輯: Schottky 來自: 118.167.25.242 (10/03 20:08)

10/03 21:25, , 1F
印象中 g++ 好像用 trunc() 去實作 round() (很不確定) XD
10/03 21:25, 1F

10/03 21:26, , 2F
這問題小弟有探討過,這類型前提都是要假設轉型後沒溢位。
10/03 21:26, 2F

10/03 21:27, , 3F
10/03 21:27, 3F

10/03 21:31, , 4F
一下就五個 round 是哪招= =
10/03 21:31, 4F

10/03 21:39, , 5F
對喔,我忘了float不能隨便轉int... :p
10/03 21:39, 5F

10/03 21:40, , 6F
+-0.5 也是個很可能爆炸的問題 @@
10/03 21:40, 6F

10/03 21:50, , 7F
+-0.5 有什麼問題?
10/03 21:50, 7F

10/04 14:24, , 8F
謝謝專業的s大
10/04 14:24, 8F
文章代碼(AID): #1IJLm0uQ (C_and_CPP)
文章代碼(AID): #1IJLm0uQ (C_and_CPP)