2023年9月30日土曜日

C言語:小数→整数への丸めの処理の違い

event_note22:46 editBy ケイ forumNo comments

概要

 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のコマンドプロンプトです。
CLコマンドでコンパイルします。

実行結果は以下の様になります。

floor関数は数値が小さい整数に、キャストは絶対値が小さい整数に丸めが行われます。

なお、floor関数の戻りはdoubleのままです。

切り捨てとして期待する処理は一般的にどちらなのでしょうか。

考察

floor関数は切り捨てとして説明されることがありますが、実際は「引数を越えない最大の整数値を返す」処理を行います。

丸めについては調べると色々な考え方があるようで、とりあえず一つの基準としてJISの規格を参考にします。

JIS規格 Z8401「数値の丸め方」ではいわゆる四捨五入で、負数の場合は絶対値に適用すると説明をしています(規則B)。
切り上げ、切り捨ての説明はありませんが同様に考えると、キャストの処理の方がJIS的と言えそうです。

JIS規格は以下から検索できます。(但しユーザー登録が必要)

負数の丸めがどのような処理とするのかは、システムで統一しておかないと不具合になりますね。そういう記事もありました。


0 comments:

コメントを投稿