vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

【C#】float における == と Equals

はじめに

先日他の方の書いたコードを見る機会があったのですが、その中で「if(num == 0f)」のような内容を見ました。

ドヤ顔で「if(num.Equals(0f))」の方が良いですよ、と言いかけたのですが、ここで一つ気になりました。

== と Equals でどう変わるんだっけ?

ということで調べてみました。

== と Equals

まずは両者の違いを見てみます。

2つの値が等しいか調べる、等値演算子(==)とEqualsメソッドの違い - .NET Tips (VB.NET,C#...)

Equality Comparisons (C# Programming Guide) | Microsoft Docs

How to: Define Value Equality for a Type (C# Programming Guide) | Microsoft Docs

参照型の比較については参照の比較と値の比較があるものの、今回の float のような値型の比較では、どちらも値を比較するようです(当然といえば当然ですが)。

値を入れて比較してみる

下記のようなコードで、 valueA と valueB の値を入れ替えて結果に違いが出るかを見てみました。

using System;

namespace ConsoleApp1 {
    class Program {
        static void Main(string[] args) {
            float valueA = 0f;
                float valueB = 0f;
            
            Console.WriteLine("result ==: " + (valueA == valueB) + 
                " equals: " + (valueA.Equals(valueB)));
        }
    }
}

比較した値と結果はこちら。

f:id:mslGt:20181002073557p:plain

Java では +0.0 と -0.0 も結果が異なるようですが、 C# では同じ結果となりました。

Float,Doubleのequalsとfloat,doubleの== - souta-bot log

ということで、調べた中では値が float.NaN であった場合のみ結果が異なる、ということになりました。

float.NaN は数値ではないため == では False になり、 Equals の場合は float.NaN の場合の処理が別に用意されているため True になる、ということでしょうか。

いずれにせよ、これなら処理上 float.NaN になることが考えられない場合は == を使う方が良さそうです(値型の場合、こちらの方が速度が速いということなので)。

指数表記

調べる中で興味深かったところとして、例えば下記のコードでは == 、 Equals ともに True になります。

using System;

namespace ConsoleApp1 {
    class Program {
        static void Main(string[] args) {
            float valueA = 10000000.12345f;
                float valueB = 10000000f;
            
            Console.WriteLine("A: " + valueA + " B: " + valueB);
            Console.WriteLine("result ==: " + (valueA == valueB) + 
                " equals: " + (valueA.Equals(valueB)));
        }
    }
}

valueA, valueB の値はどちらも 「1E+07」と出力され、どうやら値が丸められているようです。

値を 1/10 すると、「1000000」となり、結果は False になります。

扱う値によっては注意が必要ですね。

おわりに

今回確認した内容がすべてか?というと自信がないですが、基本的には float の比較は == で良さそう、ということが分かりました。

まぁ Equals を使ったとして問題になることも無いとは思いますが、やっぱりちゃんと把握しないといけませんね。

参照