作者Schottky (Schottky)
看板C_and_CPP
標題Re: [問題]有關 round() 的問題
時間Thu Oct 3 19:58:53 2013
※ 引述《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)
→ Feis:印象中 g++ 好像用 trunc() 去實作 round() (很不確定) XD 10/03 21:25
推 EdisonX:這問題小弟有探討過,這類型前提都是要假設轉型後沒溢位。 10/03 21:26
推 damody:一下就五個 round 是哪招= = 10/03 21:31
→ Schottky:對喔,我忘了float不能隨便轉int... :p 10/03 21:39
→ Feis:+-0.5 也是個很可能爆炸的問題 @@ 10/03 21:40
→ Schottky:+-0.5 有什麼問題? 10/03 21:50
推 watson1988:謝謝專業的s大 10/04 14:24