none
Math.Roundって五捨六入? RRS feed

回答

  • 上記 URL の「戻り値」のセクションにも説明がありますが、IEEE 規格の丸めは四捨五入とは異なります。
    単純な四捨五入であれば、Math.Round(3.45, 1) は 3.5 になるはずですが、IEEE の丸めは中間値を偶数側に寄せるので、3.4 になっていることに注目してください。 

    ちなみに、Math.Round(3.55, 1) だと 3.6 が、Math.Round(3.65, 1) でも 3.6 が返ります。
    2011年6月27日 6:04
  • そのために、MidpointRoundingを引数にとるバージョンがあるようですね。

    Math.Round(3.45, 1, MidpointRounding.AwayFromZero) => 3.5

    2011年6月27日 6:25
  • VB6からVB2005にアップグレードをかけているのですが

    何かの時にMath.Roundが出てきて便利だと思い従来の(VB6、VBA、SQLServerでも)

    ROUNDの代わりに使っていたのですが今回ハマりました

    誤解がある気がしますが、確かVB6とかも四捨五入じゃないはずですよ。

     

    2011年6月27日 6:51
  • AwayFromZero は四捨五入じゃありませんよ、名前の通りゼロより遠いほうに丸める処理です。四捨五入は、+0.5 して Floor するのが一般的な処理ではないでしょうか。

    ※ 具体的には、AwayFromZero の場合は -3.5 は -3 ではなく -4 に丸められます。(-3 よりも -4 のほうが 0 から遠いため)

    数直線で考えるとよいと思いますよ。「プラス無限大側に丸める」のが、Ceiling で、「マイナス無限大側に丸める」のが Floor、「0より遠い側(無限大)に丸める」のが AwayFromZero で、「偶数に丸める」のが ToEven です。これらはどれもコンピュータの世界では一般的に使われる丸め方です。

    2011年6月27日 6:52
  • > 誤解がある気がしますが、確かVB6とかも四捨五入じゃないはずですよ。

    確認しましたが、VB6 でも ROUND() は偶数への丸めです。

    2011年6月27日 8:25

すべての返信

  • 上記 URL の「戻り値」のセクションにも説明がありますが、IEEE 規格の丸めは四捨五入とは異なります。
    単純な四捨五入であれば、Math.Round(3.45, 1) は 3.5 になるはずですが、IEEE の丸めは中間値を偶数側に寄せるので、3.4 になっていることに注目してください。 

    ちなみに、Math.Round(3.55, 1) だと 3.6 が、Math.Round(3.65, 1) でも 3.6 が返ります。
    2011年6月27日 6:04
  • そのために、MidpointRoundingを引数にとるバージョンがあるようですね。

    Math.Round(3.45, 1, MidpointRounding.AwayFromZero) => 3.5

    2011年6月27日 6:25
  • 早速のご返事ありがとうございます

    VB6からVB2005にアップグレードをかけているのですが

    何かの時にMath.Roundが出てきて便利だと思い従来の(VB6、VBA、SQLServerでも)

    ROUNDの代わりに使っていたのですが今回ハマりました

    第3引数に MidpointRounding.AwayFromZero

    って書けばいいんじゃないかということで一人納得いたしました

     

     

    2011年6月27日 6:39
  • VB6からVB2005にアップグレードをかけているのですが

    何かの時にMath.Roundが出てきて便利だと思い従来の(VB6、VBA、SQLServerでも)

    ROUNDの代わりに使っていたのですが今回ハマりました

    誤解がある気がしますが、確かVB6とかも四捨五入じゃないはずですよ。

     

    2011年6月27日 6:51
  • AwayFromZero は四捨五入じゃありませんよ、名前の通りゼロより遠いほうに丸める処理です。四捨五入は、+0.5 して Floor するのが一般的な処理ではないでしょうか。

    ※ 具体的には、AwayFromZero の場合は -3.5 は -3 ではなく -4 に丸められます。(-3 よりも -4 のほうが 0 から遠いため)

    数直線で考えるとよいと思いますよ。「プラス無限大側に丸める」のが、Ceiling で、「マイナス無限大側に丸める」のが Floor、「0より遠い側(無限大)に丸める」のが AwayFromZero で、「偶数に丸める」のが ToEven です。これらはどれもコンピュータの世界では一般的に使われる丸め方です。

    2011年6月27日 6:52
  • 四捨五入という言葉の意味に、負数での振る舞いまで規定されていましたっけ…? 正数だけ意図通りになれば十分かと思っていました。
    2011年6月27日 6:59
  • 負の数の四捨五入は色々な流儀があるので、業務要件次第でどう振る舞うかを規定する必要があると思います。
    ちなみに Excel の四捨五入関数 (Round) だと、0 から遠い方に寄せるようです。(つまり、佐祐理さん方式)

    2011年6月27日 7:35
  • > 誤解がある気がしますが、確かVB6とかも四捨五入じゃないはずですよ。

    確認しましたが、VB6 でも ROUND() は偶数への丸めです。

    2011年6月27日 8:25
  • 四捨五入という言葉の意味に、負数での振る舞いまで規定されていましたっけ…? 正数だけ意図通りになれば十分かと思っていました。


    負については厳密ではないと思います。なので、「四捨五入」とい言葉と AwayFromZero については前の投稿の通りです。

    VB6 との互換性の問題だと FIX(value+0.5) または INT(value+0.5) と記述することが多いと思いますが、前者の場合 0 に近づくように丸めらえるので、VB6 との互換性という意味では AwayFromZero でも Ceiling でも Floor でもダメなんですよね。後者については前の投稿の通り。

    2011年6月27日 8:31
  • 「AwayFromZero は四捨五入じゃありませんよ」という出だしが、「(厳密ではない)四捨五入の定義と異なる」と主張されていたので指摘しただけです。

    AwayFromZeroの振る舞いについては指摘していませんし、それについてはK. Takaokaさんの書かれている通りです。

    2011年6月27日 8:37
  • あれ? 私は

    > 四捨五入という操作が負の値について厳密ではないので、「AwayFromZero は、四捨五入である」とするのは問題があります。

    という意図なのですが、佐祐理さんは、

    > 四捨五入という操作が負の値について厳密ではないので、「AwayFromZero は、四捨五入である」とみなせる。

    と、いわれているのですよね。未定義操作を論じているわけでもないので、私にはそういう解釈はできない/したくないですね、というだけです。

    2011年6月27日 9:48
  • あれ? 私は

    > 四捨五入という操作が負の値について厳密ではないので、「AwayFromZero は、四捨五入である」とするのは問題があります。

    という意図なのです

    おそらく、最初の投稿にその注意書きを添えていればよかったのではないでしょうか。
    その辺を踏まえずに、「四捨五入ではない」と断じたのは、話が飛びすぎているかなと思いました。

    # 四捨五入とみなせる・みなせないは客観的な話にならないので、特にコメントせず。
    # あと、脱線気味なので。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2011年6月27日 14:00
    モデレータ
  • 返信ありがとうございました

    お恥ずかしい話ですがroundについて言語により差があるなんて今まで全く気付きませんでした(^^;;

    VB6,VBA,VB.netはご指摘の通りです

    同じExcelでもセルに直接=round(2.5,0)とすると認識通りの様です

    SQLServerはselect round(1.5,0),round(2.5,0)

    では2.0、3.0と帰ってきますのでほっとしました

    これからは気を付けていきたいと思います

     

    2011年6月29日 0:04