概要
C言語で小数→整数への丸めをするとき、floor関数とint型へのキャストで結果が違うことに最近気づきました。
正の値であれば同じなんですが、負の値だと異なる結果となります。
検証
実際にプログラムで検証します。
#include<stdio.h> #include<math.h> int main() { double val[] = {.5, 1.5, -.5, -1.5}; for(int t=0; t<sizeof(val)/sizeof(double); t++) { printf("val=%5.1f (int)val=%3d floor(val)=%3.0f\n", val[t], (int)val[t], floor(val[t])); } } |
検証環境はVisual Studio 2019のコマンドプロンプトです。
floor関数は数値が小さい整数に、キャストは絶対値が小さい整数に丸めが行われます。
なお、floor関数の戻りはdoubleのままです。
切り捨てとして期待する処理は一般的にどちらなのでしょうか。
考察
floor関数は切り捨てとして説明されることがありますが、実際は「引数を越えない最大の整数値を返す」処理を行います。
丸めについては調べると色々な考え方があるようで、とりあえず一つの基準としてJISの規格を参考にします。
JIS規格 Z8401「数値の丸め方」ではいわゆる四捨五入で、負数の場合は絶対値に適用すると説明をしています(規則B)。
切り上げ、切り捨ての説明はありませんが同様に考えると、キャストの処理の方がJIS的と言えそうです。
JIS規格は以下から検索できます。(但しユーザー登録が必要)
負数の丸めがどのような処理とするのかは、システムで統一しておかないと不具合になりますね。そういう記事もありました。
コメントを投稿