Recently Andrew “Sniper” Smith posted this entry, 0 == 0 … well, usually it does on his blog. Very good post on the subject as are all his deep blog entries.
After reading it, I got real interested and wrote the below VB.NET console application to learn what I could about this “0 = 0″ and ”0 = -0″ business.
All results are what you would expect, except for the last group of tests. These caught me by surprise. I have named these test results the cockroaches. Please look for the roach icon below and compare the code with the output.
Cockroach defined: A cockroach is not a bug in the code, it’s a little surprise or gotcha. Like real cockroaches sometimes very difficult to find, correct and/or remove.
All the tests above the cockroaches return expected results, the values are equal.
You can download the Console Application using the below link. After downloading, you MUST change the file extension from .zip.DOC to .zip and then extract the .zip file. This is a requirment of WordPress.com.
Download Source Code
Module Module1
Debug.WriteLine(“”)
Debug.WriteLine(“——————————-”)
Debug.WriteLine(“”)
Dim intZ As Integer = 0
Dim intNZ As Integer = -0
Dim intZ2 As Integer = 0
Debug.WriteLineIf(intZ <> intNZ, _
“intZ <> intNZ”)
Debug.WriteLineIf(intZ * 1.12 <> intNZ * _
1.12, “intZ * 1.12 <> intNZ * 1.12″)
Debug.WriteLineIf(Not Integer.Equals(intZ, _
intNZ), “Not Integer.Equals(intZ, intNZ)”)
Debug.WriteLineIf(Not intZ.Equals(intNZ), _
“Not intZ.Equals(intNZ)”)
Debug.WriteLineIf(Not Integer.Equals(intZ, _
intZ2), “Not Integer.Equals(intZ, intZ2)”)
Debug.WriteLineIf(Not intZ.Equals(intZ2), _
“Not intZ.Equals(intZ2)”)
Debug.WriteLineIf(Not Integer.Equals(0, -0), _
“Integer.Equals(0,-0)”)
Debug.WriteLineIf(Not intNZ.Equals(0), _
“Not intNZ.Equals(0)”)
Dim strZ As String = “0″
Dim strNZ As String = “-0″
Debug.WriteLineIf(CType(strZ, Integer) <> _
CType(strNZ, Integer), _
“CType(strZ, Integer) <> CType(strNZ, Integer)”)
Debug.WriteLineIf(CInt(strZ) <> CInt(strNZ), _
“CInt(strZ) <> CInt(strNZ)”)
Debug.WriteLineIf(Integer.Parse(strZ) <> _
Integer.Parse(strNZ), _
“Integer.Parse(strZ) <> Integer.Parse(strNZ)”)
Dim sngZ As Single = 0.0
Dim sngNZ As Single = -0.0
Debug.WriteLineIf(sngZ <> sngNZ, _
“sngZ <> sngNZ”)
Debug.WriteLineIf(sngZ * 1.13 <> sngNZ * _
1.12, “sngZ * 1.13 <> sngNZ * 1.12″)
Debug.WriteLineIf(Not Single.Equals(sngZ, _
sngNZ), “Not Single.Equals(sngZ, sngNZ)”)
‘double
Dim dblZ As Double = 0.0
Dim dblNZ As Double = -0D
Debug.WriteLineIf(dblZ <> dblNZ, _
“dblZ <> dblNZ”)
Debug.WriteLineIf(dblZ * 2.56 <> dblNZ * _
2.57, “dblZ * 2.56 <> dblNZ * 2.57″)
Debug.WriteLineIf(Not Double.Equals(dblZ, _
dblNZ), “Not Double.Equals(dblZ, dblNZ)”)
Debug.WriteLineIf(Not dblZ.Equals(dblNZ), _
“Not dblZ.Equals(dblNZ)”)
‘decimal
Dim decZ As Decimal = 0
Dim decNZ As Decimal = -0
Debug.WriteLineIf(decZ <> decNZ, _
“decZ <> decNZ”)
Debug.WriteLineIf(decZ * 0.003 <> decNZ * _
0.008, “decZ * 0.003 <> decNZ * 0.008″)
Debug.WriteLineIf(Decimal.Compare(decZ, _
decNZ) <> 0, _
“Decimal.Compare(decZ, decNZ) <> 0″)
Debug.WriteLineIf(Not decZ.Equals(decNZ), _
“Not decZ.Equals(decNZ)”)
Debug.WriteLineIf(Decimal.Parse(“0.00″) <> _
decNZ, “Decimal.Parse(‘0.00′) <> decNZ”)
Debug.WriteLineIf(Decimal.Parse(“0.00″) <> _
Decimal.Parse(“-0″), _
“Decimal.Parse(‘0.00′) <> Decimal.Parse(‘-0′)”)
‘==============================================================
‘these do not fail
Debug.WriteLineIf(Not Integer.Equals(“0″, _
“0″), “Not Integer.Equals(‘0′, ‘0′)”)
Debug.WriteLineIf(Not Single.Equals(“0″, _
“0″), “Not Single.Equals(‘0′, ‘0′)”)
Debug.WriteLineIf(Not Double.Equals(“0″, _
“0″), “Not Double.Equals(‘0′, ‘0′)”)
Debug.WriteLineIf(Not Decimal.Equals(“0″, _
“0″), “Not Decimal.Equals(‘0′, ‘0′)”)
‘here are the cockroaches, they all return not equal

Debug.WriteLine(“Below are the cockroaches ———-”)
Debug.WriteLineIf(Not Integer.Equals(“0″, _
“-0″), “Not Integer.Equals(‘0′, ‘-0′)”)
Debug.WriteLineIf(Not Single.Equals(“0″, _
“-0″), “Not Single.Equals(‘0′, ‘-0′)”)
Debug.WriteLineIf(Not Double.Equals(“0″, _
“-0″), “Not Double.Equals(‘0′, ‘-0′)”)
Debug.WriteLineIf(Not Decimal.Equals(“0″, _
“-0″), “Not Decimal.Equals(‘0′, ‘-0′)”)
Debug.WriteLineIf(Not Integer.Equals(strZ, _
strNZ), “Not Integer.Equals(strZ, strNZ)”)
Debug.WriteLineIf(Not Single.Equals(strZ, _
strNZ), “Not Single.Equals(strZ, strNZ)”)
Debug.WriteLineIf(Not Double.Equals(strZ, _
strNZ), “Not Double.Equals(strZ, strNZ)”)
Debug.WriteLineIf(Not Decimal.Equals(strZ, _
strNZ), “Not Decimal.Equals(strZ, strNZ)”)
Debug.WriteLine(“——————————-”)
End Sub
End Module
Debug.WriteLineIf Output From Code

Not Integer.Equals(‘0′, ‘-0′)
Not Single.Equals(‘0′, ‘-0′)
Not Double.Equals(‘0′, ‘-0′)
Not Decimal.Equals(‘0′, ‘-0′)
Not Integer.Equals(strZ, strNZ)
Not Single.Equals(strZ, strNZ)
Not Double.Equals(strZ, strNZ)
Not Decimal.Equals(strZ, strNZ)
———————————————-
All of the above Type’s .Equals methods take a parameter of Type Object. If you pass in a string, this method returns not equal. If you pass a parameter of the same Type as the Type, then .Equals returns equal, providing the other value it’s comparing is actually equal.
The object browser for Int32, fine print states that the method returns true if the object is an instance of System.Int32. This is why the tests fail. I’m passing in a System.String object. However, other places in the .NET framework that call for an object, we can get away with passing System.String and get the expected results, not here.
Public Overrides Function Equals(ByVal obj As Object) As BooleanMember of System.Int32
Summary: Returns a value indicating whether this instance is equal to a specified object.
Parameters: obj: An object to compare with this instance.
Return Values: true if obj is an instance of System.Int32 and equals the value of this instance; otherwise, false.
Moral of the story is, if you need to compare strings that are numbers, cast them first before comparing them, and not rely on the .Equals method to do this for you because it won’t. As you can see, this applies to Integer, Single, Double & Decimal types too.
This is another case for Type Safe Code!
These lines are equal
Debug.WriteLineIf(Not Integer.Equals(CInt(“0″),_
These lines fail and are NOT equal
Just a grain of sand on the worlds beaches.


