hnwの日記

Monoで巨大な浮動小数点数を丸めたら無限大になった

Monoのround関数にバグを見つけたよ、という毎度おなじみの話題です。


早速ですが、浮動小数点数で扱える一番大きい数を浮動小数点数以下第2位で丸めて第1位までにしてみましょう。

using System;
class RoundingBigFloat
{
    static void Main()
    {
        double d = Double.MaxValue;
        Console.WriteLine(d); // 1.79769313486232E+308
        Console.WriteLine(Math.Round(d, 1)); // Infinity
    }
}


上記コードのコメント部の通り、大きい数を丸めると無限大になることがあります。これは、小数点以下第n位までに丸める処理が、「10^n倍して整数に丸めて10^-n倍する」という処理になっているため、この計算の途中で無限大になってしまうことがあるのです。

Monoのソースコードも見てみた

対応するMonoの処理を追ってみましょう。MonoのC#コンパイラmcsはC#で書かれています。

続きを読む