いぬおさんのおもしろ数学実験室

おいしい紅茶でも飲みながら数学、物理、工学、プログラミング、そして読書を楽しみましょう

ガウス記号を使って小数点以下の任意の桁を四捨五入する

 UnityにはMathfというクラスがあって、様々な数学の関数が使えます。例えばMathf.Sin()でsinを計算できます。プログラムに出てくる数値を四捨五入する必要があり、探したらMathf.Round()というのが見つかりました。ただ、これは名前からして「丸め」だけれど、四捨五入ではありません。例えば……

Mathf.Round(8.5) = 8

Mathf.Round(8.6) = 9

Mathf.Round(9.5) = 10

で、小数第1位が5以外なら四捨五入と同じですが、5のときは異なります。「最も近い偶数に丸める」ということです。「銀行家の丸め」と言うそうな。集計の際の誤差が通常の四捨五入を使ったときより小さくなるそうです。Roundだから四捨五入かと思ったら違っていて、「何で……?」と思いました。また、「小数第5位を四捨五入」などは直接はできません。じゃあ、……ということで、C#のRound()を使おうとしたらいくつかエラーが出てうまくいきません。Unityとの関係?

 とりあえず四捨五入は早く使いたいので、工夫します。Mathf.Round()は通常の四捨五入ではないですし、しかも整数を返すだけです。新しくround(x, m)という関数を自分で作り、xの小数第m位を四捨五入した値を返すようにしたいのです。

 MathfにはFloor()という関数があります。切り捨てです。つまりMathf.Floor(x)はx以下の最大の整数を返します。数学で言うガウス記号ですね。例えば次のようになります。

Mathf.Floor(8.5) = 8

Mathf.Floor(8.6) = 8

Mathf.Floor(9.5) = 9 

Mathf.Floor(10) = 10

これを使います。具体例を考えると分かりやすいと思います。例えば

x=1234.5678 を小数第3位で四捨五入してみましょう。切り捨ての記号は[ ](ガウス記号)を使うことにします。 

f:id:Inuosann:20210222202939p:plain

でよいでしょう。x = 1234.5678 のときと、x = 1234.5638 のときにどうなるか、式に代入してみてください。正しく計算されることが分かります。一般に、小数第m位を四捨五入したければ次のようにすればよいのです。

f:id:Inuosann:20210222203131p:plain

あとは[ ] をMathf.Floor()で置き換えればOKです。

 あるいはコードで if 文を使ってもできるでしょう。どちらの方がよいのか(特に計算が速くなるのか)分かりませんが。しかしなんでそもそも、四捨五入がないんでしょうか……。