C言語で割り算結果を「切り捨て」「四捨五入」「切り上げ」する方法

切り捨て四捨五入切り上げの解説ページのアイキャッチ

このページでは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言語のキャストについて解説!「符号あり」と「符号なし」の比較・計算は特に危険!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です