C言語における割り算の、小数点以下を四捨五入する場合について記載します。
小数点以下を切り上げする場合については 「整数の割り算で小数点を切り上げる」 を参照ください。
整数の四捨五入
C言語で割り算の四捨五入を行いたい場合は以下のように書くことができます。
この例は math.h や double を使う非常にリッチな方法です。
1. |
2. |
3. |
4. |
5. |
6. |
7. |
8. |
9. |
10. |
11. |
12. |
13. |
14. |
15. |
16. |
17. |
18. |
19. |
20. |
21. |
|
#include <math.h> |
|
double myWaruKazu = 5u; |
double myWarareruKazu = 6u; |
unsigned int myResult; |
|
double myWork; |
double myLower; |
|
|
myResult = (unsigned int) (myWarareruKazu / myWaruKazu); |
|
|
myLower = modf( myWarareruKazu / myWaruKazu, &myWork ); |
|
|
if( 0.5 <= myLower ){ |
myResult++; |
} |
|
|
|
[2012.01.15] 上記の式が正しいことを、100000*100000回の試験にて確認しました
パフォーマンスを上げた式
上の式は非常にリッチな書き方でしたので、次の例では math.h も double も使わず書いてみます。
1. |
2. |
3. |
4. |
5. |
6. |
7. |
8. |
9. |
|
unsigned int myWaruKazu = 5u; |
unsigned int myWarareruKazu = 6u; |
unsigned int myResult; |
|
|
myResult = (myWarareruKazu * 10u) / myWaruKazu; |
|
|
myResult = (myResult + 5u) / 10u; |
|
[2012.01.15] 上記の式が正しいことを、100000*100000回の試験にて確認しました
パフォーマンスを上げ、扱える範囲を大きくした式
上の式でパフォーマンスが上がりましたが、割られる数を10倍してしまっています。
これによって割られる数として扱える範囲が1/10まで減少してしまいました。
この点を改善して割る数として扱える範囲が1/2まで減少するだけで済む式にしてみました。
1. |
2. |
3. |
4. |
5. |
6. |
7. |
8. |
9. |
10. |
11. |
12. |
13. |
|
|
unsigned int myWaruKazu = 5u; |
unsigned int myWarareruKazu = 6u; |
unsigned int myResult; |
|
|
myResult = myWarareruKazu / myWaruKazu; |
|
|
if( myWaruKazu <= ( (myWarareruKazu % myWaruKazu) * 2u) ){ |
myResult++; |
} |
|
|
[2012.01.15] 上記の式が正しいことを、100000*100000回の試験にて確認しました
ついでにマクロにしよう
上記の式を #define で仮引数付きマクロ _DIVRND() にしてみました。
_UNSAFE_DIVRNDはゼロ割に対応していません。(vWaruがゼロだとヤバい)
|
#define _DIVRND( vWarareru, vWaru ) ( !(vWaru) ? 0 : _UNSAFE_DIVRND( vWarareru, vWaru ) ) |
#define _UNSAFE_DIVRND( vWarareru, vWaru ) ( ( ( (vWarareru) % (vWaru) ) *2 ) >= (vWaru) ? |
( ( (vWarareru) / (vWaru) ) + 1u) : |
( ( (vWarareru) / (vWaru) ) ) ) |
|
|
[2012.01.15] 上記の式が正しいことを、100000*100000回の試験にて確認しました