【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))); } } }
比較した値と結果はこちら。
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 を使ったとして問題になることも無いとは思いますが、やっぱりちゃんと把握しないといけませんね。
参照
- Double Struct (System) - Microsoft Docs
- Single.Equals Method (Object) (System) - Microsoft Docs)
- 2つの値が等しいか調べる、等値演算子(==)とEqualsメソッドの違い - .NET Tips (VB.NET,C#...) - dobon.net
- How to: Define Value Equality for a Type (C# Programming Guide) - Microsoft Docs
- Equality Comparisons (C# Programming Guide) - Microsoft Docs
- 連載! とことん C#: 第 4 回 型について知ろう (decimal と double/float の違い) 言語: C# - msdn
- Single.NaN Field (System) - Microsoft Docs
- c# - Single.NaN doesn't equal itself? - Stack Overflow