Showing posts with label double equals. Show all posts
Showing posts with label double equals. Show all posts

Thursday, February 27, 2014

C#: Inconsistent behavior of equality

Learning AngularJS; Guide for beginners:

In C# equality is quite confusing, you might see many cases where obvious thing result in an unexpected result.










Here are some cases to illustrate a bit of different output of equalities.

see here demo

int _Int = 1;
short _Short = 1;
object _objectInt1 = _Int;
object _objectInt2 = _Int;
object _objectShort = _Short;
Console.WriteLine(_Int == _Short);   // case 1 true
Console.WriteLine(_Short == _Int);   // case 2 true
Console.WriteLine(_Int.Equals(_Short));   // case 3 true
Console.WriteLine(_Short.Equals(_Int));   // case 4 false
Console.WriteLine(_objectInt1 == _objectInt1);   // case 5 true
Console.WriteLine(_objectInt1 == _objectShort);  // case 6 false
Console.WriteLine(_objectInt1 == _objectInt2);   // case 7 false
Console.WriteLine(Equals(_objectInt1, _objectInt2));  // case 8 true
Console.WriteLine(Equals(_objectInt1, objectShort)); // case 9 false

How these cases are working?


Console.WriteLine(_Int == _Short); // case 1 true
Console.WriteLine(_Short == _Int); // case 2 true


For case one and two we must first determine what the == operator means here. C# defines over a dozen different built-in == operators:
string == string
object == object
ulong == ulong
uint == uint
int == int
long == long
...
There is no comparison operator for different data types comparison i.e, int == short or short == int, So for this there other possibilities in available operator will be determined, the best match for the case is int == int or short == short but implicit conversion of int to short is not possible and error prone. So the short is converted to int and then the two values are compared as numbers. They are therefore equal as both holds the same value.

Console.WriteLine(_Int.Equals(_Short)); // case 3 true


In case three we must first find which overloaded methods from available methods is invoked here. The Equals() here is called by a type int and it has three methods named Equals:
Equals(object, object) // static method from object
Equals(object)         // virtual method from object
Equals(int)            // Implements IEquatable.Equals(int)
The first one we can eliminate because there are different count of arguments, Of the other two, the unique best method is the one that takes an int; it is always better to convert the short argument to int than to object. Therefore we call Equals(int), which then compares the two integers again using value equality, so this is true.

Console.WriteLine(_Short.Equals(_Int)); // case 4 false!


In scenario four we again must determine what Equals means. The receiver is of type short which again has three methods named Equals
Equals(object, object) // static method from object
Equals(object)         // virtual method from object
Equals(short)          // Implements IEquatable.Equals(short)
Overload resolution eliminates the first because there are too few arguments and eliminates the third because there is no implicit conversion from int to short. That leaves short.Equals(object), which has the moral equivalent of this implementation:
bool Equals(object z)
{
  return z is short && (short)z == this;
}
That is, for this method to return true the argument passed in must be a boxed short, and when unboxed it must be equal to the receiver. Since the argument is a boxed int, this returns false. There is no special gear in this implementation that says “well, what if I were to convert myself to the type of the argument and then compare?”

Console.WriteLine(_objectInt1 == _objectInt1); // case 5 true
Console.WriteLine(_objectInt1 == _objectShort); // case 6 false!!
Console.WriteLine(_objectInt1 == _objectInt2); // case 7 false!!!



In scenarios five, six and seven operator overload resolution chooses the object == object form, which is equivalent to a call to Object.ReferenceEquals. Clearly the two references are equal in case five and unequal in cases six and seven. Whether the values of the objects when interpreted as numbers are equal does not come into play at all; only reference equality is relevant.


Console.WriteLine(Equals(_objectInt1, _objectInt2)); // case 8 true
Console.WriteLine(Equals(_objectInt1, objectShort)); // case 9 false

In scenarios eight and nine operator overload resolution chooses the static method Object.Equals, which you can think of as being implemented like this:
public static bool Equals(object x, object y)
{
    if (ReferenceEquals(x, y)) return true;
    if (ReferenceEquals(x, null)) return false;
    if (ReferenceEquals(y, null)) return false;
    return x.Equals(y);
}
In scenario eight we have two references that are unequal and not null; therefore we call int.Equals(object), which as you would expect from our previous discussion of short.Equals(object) is implemented as the moral equivalent of:
bool Equals(object z)
{
  return z is int && (int)z == this;
}
Since the argument is of type int it is unboxed and compared by value. In scenario nine the argument is a boxed short and so the type check fails and this is false.


We discussed nine different methods that two things can be compared for equality, despite the fact that we have always same input of 1 in both side of comparison, equality is true in only half the cases. If you think this is crazy and confusing, you’re right! Equality is tricky in C#.

Saturday, January 4, 2014

JavaScript Triple Equals Operator vs Double Equals Operator ( === vs == )

You may also like to see:








Comparing two values in any language is the most used operations. In many cases you may need to compare different variables values, that is the reason in many JavaScript code you will find the following lines:


if (age == years) {  
    // do something here  
}  

or JavaScript which follows best practices, you will find:

if (age === years) {  
    // do something here  
}  

Operation in the first example is also called "lenient" or "normal" equality while the latter one is also called “strict” or “identical” equality.

Why different operator?

When a comparison is made using a double-equals operator, it will check the values of a variable and convert them to a common type and returns true if both are equals. So comparing number with a string having the same value will return true.

JavaScript supports different data types which includes string, number, booleans, array, object, function, null and undefined. When comparing different types with double equals operator an implicit conversion is occurring and then the comparison is made. This conversion is made for boolean to a number when comparing numbers with boolean, or number to string when comparing string with numbers.

This conversion not only an overhead but also give unexpected(wrong) output in many cases.

Here are some examples:

console.log(23 == "23"); // true  
console.log(1 == true); // true  

Some programmers find it useful that auto-conversion is making it easy to compare, but it is not always the case. It may cause serious issues.

For example:

console.log(' \r\t\n' == 0); // true  
console.log(0 == ' '); // true  

Here in these cases space is converted to false or zero which causing the result true in both above cases. Which may cause your comparison to going in wrong directions.

That is the reason most of the JavaScript expert programmers use and recommend triple-equals operator instead of the double-equals operator.

As Douglas Crockford's stated in his book JavaScript: The Good Parts:

JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=. The good ones work the way you would expect. If the two operands are of the same type and have the same value, then === produces true and !== produces false. The evil twins do the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values. the rules by which they do that are complicated and unmemorable. These are some of the interesting cases:


'' == '0'   // returns false
    0 == ''             // returns true
    0 == '0'            // returns true

    false == 'false'    // returns false
    false == '0'        // returns true

    false == undefined  // returns false
    false == null       // returns false
    null == undefined   // returns true

    ' \t\r\n ' == 0     // returns true

In contrast to double equals operator, another operator with three equals not made the implicit conversion so it not only compare values but also the type of variable that's why it is also called strict comparison.

Due to not implicit conversion, it is not only better in performance but guarantees the correct results always.

Here are examples:

console.log(23 === "23");  // returns false  
console.log(1 === true);  // returns false  
console.log(' \t\r\n' === 0); // returns false  
console.log(0 === ' '); // returns false  

Not-Equals to Operator?

Same situation or output is return when not-equals to comparison is made between two variables using != or !== operators

Here are examples:

console.log(23 != "23"); // false  
console.log(1 != true); // false  
console.log(' \t\r\n' != 0); // false  
console.log(0 != ' '); // false  

As expected result should be true from the above comparison but due to implicit conversion, all comparison returns true.

To make it work correctly use !== operator:

console.log(23 !== "23"); // true  
console.log(1 !== true); // true  
console.log(' \t\r\n' !== 0); // true  
console.log(0 !== ' '); // true  

Comparison in Reference Types

When comparing non-primitive data types (reference types) both operators behave consistent (except in some cases discussed below)

Here are some example:
var arrayOne = [1,2,3];
var arrayTwo = [1,2,3];

var objectOne = { x: 1, y: 2 };
var objectTwo = { x: 1, y: 2 };

arrayOne == arrayTwo    // false
arrayOne === arrayTwo   // false

objectOne == objectTwo   // false
objectOne === objectTwo  // false

A special case is the one when you comparing primitive type with an object that returns the same primitive type due to valueOf or toString methods. The special cases include comparing primitive string compare to new String() object or primitive number compare with a new Number() object or same for boolean.

Here are examples:

new String("abc") == "abc"   // returns true
new String("abc") === "abc" // returns false

Here triple equals operator returned false as it matches types of both sides which are string and object. while double equals operator returned true it matches value after conversion.


Performance Comparison

When comparing two variables of the same data type, both operator takes almost equal time. But if the type is not the same triple equals operator will be faster because it would not try to convert the types of variable causing it sooner to exit than double equals operator.

Here another point to notice is that the triple equals operator has one extra character, so using it might increase the JavaScript file size which may take the time to load but this is negligible.

Performance Test of both operator with same and different data types.

So, I may conclude it by recommending always to use triple equals operators, which may sometime make you to do explicit conversion but it prevent from unexpected and wrong output. It is one best practice recommend by many JavaScript experts. Like Douglas Crockford's says:

The lack of transitivity is alarming. My advice is to never use the evil twins. Instead, always use === and !==.

You may also like to see:
Life insurance policy, bank loans, software, microsoft, facebook,mortgage,policy,