このページではC言語で割り算結果の小数点以下を「切り捨て」「四捨五入」「切り上げ」する方法について解説します。整数同士の割り算についての解説になります。
方法としては2種類あります。一つは自力で計算する方法、もう一つは関数を使用する方法です。
自力で計算する方法
まずは自力で計算する方法です。整数同士の割り算結果であればこの自力で計算する方法で十分です。
スポンサーリンク
切り捨て
切り捨ては非常に簡単で、そのまま割り算した結果を代入すれば勝手に切り捨てされます。
int x; /* 被序数 */
int y; /* 序数 */
int ans; /* 計算結果 */
/* 計算 */
ans = x / y;
x も y も int 型ですので、計算結果も int 型に暗黙の型変換が行われます。小数点以下は int 型へ型変換されるときに切り捨てされますので、結果的に単純に割り算を計算すれば切り捨てが実現されることになります。
スポンサーリンク
四捨五入
四捨五入は割り算結果に 0.5 を足し、さらにその結果を小数点以下で切り捨てすることで実現できます。
int x; /* 被序数 */
int y; /* 序数 */
int ans; /* 計算結果 */
/* 計算 */
ans = (double)x / (double)y + 0.5;
小数点以下が 0.5 以上の場合、0.5 を足せば整数部が 1 繰り上がりますし、0.5未満の場合は 0.5 を足しても整数部は変わりません。
なので、この 0.5 を足した結果を小数点以下で切り捨てすれば、結果的に小数点以下で四捨五入したことになります。
ただし、切り捨てでも解説したように x と y は int 型のため、x / y を行った時点で小数点以下は切り捨てされてしまいます。切り捨てされた後に 0.5 を足しても絶対に整数部の繰り上がりは起こりませんので四捨五入になりません。
ですので、四捨五入をする場合は小数点以下も扱える double や float 型にキャストしてから割り算を行います。ここが注意点です。
切り上げ
四捨五入と同様の考え方で、下記のように 0.99999… を足して int 型への型変換で小数点以下を切り捨てれば切り上げすることはできます。
int x; /* 被序数 */
int y; /* 序数 */
int ans; /* 計算結果 */
/* 計算 */
ans = (double)x / (double)y + 0.999999;
ただ整数同士の割り算の計算結果を切り上げする場合は、もうちょっとエレガントな書き方があります。下記のようにソースコードを記述すれば切り上げすることが可能です。
int x; /* 被序数 */
int y; /* 序数 */
int ans; /* 計算結果 */
/* 計算 */
ans = (x + y - 1) / y;
なぜこれで小数点以下の切り上げができるのかを解説していきます。
まずは割り算の結果についてちょっと考えてみましょう。
例えば除数を 3 とし、被除数を 1 から 6 に変化させた場合の割り算結果は下記のようになります。
- 1 / 3 = 1 / 3
- 2 / 3 = 2 / 3
- 3 / 3 = 1
- 4 / 3 = 1 + 1 / 3
- 5 / 3 = 1 + 2 / 3
- 6 / 3 = 2
注目していただきたいのが小数点以下の値です。0 以外で考えると一番小さい値が 1 / 3 ですね。除数を 3 にしたから 1 / 3 になりますが、除数を 7 にした場合は一番小さい小数点以下の値は 1 / 7 になります(0 以外だと)。
つまり割り算結果において、小数点以下の取りうる一番小さい値は 1 / 除数 となります(0 以外だと)。
で、ここで小数点以下の切り上げについて考えると、これは小数点以下が 0 以外の場合に整数部を 1 繰り上げる処理と言えます。
そして割り算結果において、0 以外で小数点以下が取りうる一番小さい値は 1 / 除数 です。
ですので、割り算結果に対して (除数 – 1)/ 除数 を足せば、小数点以下が 0 の場合以外は整数部が繰り上がることになります。さらにこの結果に対して切り捨てを行えば(つまり int 型へ型変換すれば)切り上げを実現できるというわけです。
int x; /* 被序数 */
int y; /* 序数 */
int ans; /* 計算結果 */
/* 計算 */
ans = (double)x / (double)y + (double)(y - 1) / (double)y;
で、この式を整理すれば最初に記載したソースコードになるというわけです。
int x; /* 被序数 */
int y; /* 序数 */
int ans; /* 計算結果 */
/* 計算 */
ans = (x + y - 1) / y;
言うほどエレガントか?と言う意見もあるかもしれませんが…。0.99999… を足すよりかはちょっと見栄えは良いかなぁと思います!
関数を使用する方法
続いて関数を使用する方法について解説します。紹介する関数は全て math.h でプロトタイプ宣言されていますので、使用する場合は math.h をインクルードする必要があります。
整数型の割り算結果を引数として渡す場合は、キャストを忘れないようにしましょう。
スポンサーリンク
切り捨て
切り捨てを行う関数は floor 関数です。
include <math.h>
double floor(double);
引数に指定された値の小数点以下を切り捨てた値が double 型で返却されます。
int x; /* 被序数 */
int y; /* 序数 */
int ans; /* 計算結果 */
/* 計算 */
ans = floor((double)x / (double)y);
スポンサーリンク
四捨五入
四捨五入を行う関数は round 関数です。
include <math.h>
double round(double);
引数に指定された値の小数点以下を四捨五入した結果が double 型で返却されます。
int x; /* 被序数 */
int y; /* 序数 */
int ans; /* 計算結果 */
/* 計算 */
ans = round((double)x / (double)y);
切り上げ
切り上げを行う関数は ceil 関数です。
include <math.h>
double ceil(double);
引数に指定された値の小数点以下を切り上げした値が double 型で返却されます。
int x; /* 被序数 */
int y; /* 序数 */
int ans; /* 計算結果 */
/* 計算 */
ans = ceil((double)x / (double)y);
スポンサーリンク
まとめ
今回は整数同士の割り算結果を切り捨て・四捨五入・切り上げを行う方法について解説しました。計算を行うプログラムの場合、必要な知識ですのでしっかり理解しておきましょう!
また今回紹介した方法はどれもキャストを利用したものになりますので、キャストの効果についても理解していただけたのではないかと思います。
キャストについては下でもまとめていますので、もっと詳しく知りたい方はこちらのページも読んでみてください。
C言語のキャストについて解説!「符号あり」と「符号なし」の比較・計算は特に危険!オススメの参考書(PR)
C言語学習中だけど分からないことが多くて挫折しそう...という方には、下記の「スッキリわかるC言語入門」がオススメです!
まず学習を進める上で、参考書は2冊持っておくことをオススメします。この理由は下記の2つです。
- 参考書によって、解説の仕方は異なる
- 読み手によって、理解しやすい解説の仕方は異なる
ある人の説明聞いても理解できなかったけど、他の人からちょっと違った観点での説明を聞いて「あー、そういうことね!」って簡単に理解できた経験をお持ちの方も多いのではないでしょうか?
それと同じで、1冊の参考書を読んで理解できない事も、他の参考書とは異なる内容の解説を読むことで理解できる可能性があります。
なので、参考書は2冊持っておいた方が学習時に挫折しにくいというのが私の考えです。
特に上記の「スッキリわかるC言語入門」は、他の参考書とは違った切り口での解説が豊富で、他の参考書で理解できなかった内容に対して違った観点での解説を読むことができ、オススメです。題名の通り「なぜそうなるのか?」がスッキリ理解できるような解説内容にもなっており、C言語入門書としてもかなり分かりやすい参考書だと思います。
もちろんネット等でも色んな観点からの解説を読むことが出来ますので、分からない点は別の人・別の参考書の解説を読んで解決していきましょう!もちろん私のサイトも参考にしていただけると嬉しいです!
入門用のオススメ参考書は下記ページでも紹介していますので、こちらも是非参考にしていただければと思います。
https://daeudaeu.com/c_reference_book/