Impossible Equalities - a JavaScript puzzle
Written by Ian Elliot   
Friday, 16 December 2011
Article Index
Impossible Equalities - a JavaScript puzzle
Solution

Solution

There are all sort of values that could have been used to create this behaviour. In general the non-strict equality operator doesn't obey the usual transitive law of equality. That is in the case of equality or any operator claiming to be an equivalence operator you expect that

if a=b and a=c then you can conclude that b=c

However for the non-strict equality operator you cannot make this assumption. That is

if a==b and a==c you cannot rely on b==c begin true.

In the case of our problem code the general situation was reduced to something more specific because the role of c  was taken as numeric zero i.e. c is set to zero giving:

if a==b and a==0 it is possible that b=0 is false.

For example, suppose a='0'  and b='' a null string then clearly

a==b

is false because as strings '0' isn't equal to '' a null string.

Now consider

a==0

As a is '0' a string that converts to zero when ToNumber('0') is called this expression is true after type conversion.

Slightly less obviously

b==0

is true because a null string has been defined as converting to zero i.e. ToNumber('') returns zero. You can confirm this by trying

alert(+'');

which displays zero.

The problem is the way that one too many strings type convert to zero - even though this behaviour can be useful when working with input boxes that have been left empty.

Pattern

At this point it is tempting to blame it all on the use of the non-strict equality operator but the conversion rules for strings to numbers is just as much to blame. In this case you probably don't want to consider a null string as being the same as a zero.

Simply swapping to the strict equality operator brings other problems with it and isn't entirely trouble free. For example if a and b are set to different objects then a===b is false even in some situations where you might want to regard the two objects as equal - e.g. string objects wrapping the same string litteral.

If you want to be sure of what is happening then it is usually best to make explicit conversions. 

For example you might write:

if(Number(a)==Number(b))alert("a equals b");
if(Number(a)==0)alert("a is zero");
if(Number(b)==0)alert("b is zero");

In this case the use of == is transitive and even if a='0' and b='' you will find that 'a equals b', 'a is zero' and 'b is zero'. The reason is that the same conversion is performed for each comparison.

JavaScript makes some conditionals easier to write and some more difficult. The real point, however, is that in an object-oriented world comparisons are inherently tricky and you always need to be very clear about what you are comparing with what and what type conversions are used in the comparison.

 

Banner

More Puzzles

Sharpen Your Coding Skills
Vertex Coverings And The Cool Kids Problem

Joe Celko has posed another puzzle that requires you to think like a programmer. This one asks us to find the cool kids in a social network - the ones who taken together know everyone else. This is al [ ... ]


PHP
Where Did The Logic Go?

Logic never goes wrong but in this case a simple refactoring of an if block seem to give a different result, even though it does exactly the same thing. Or does it? This Programmer Puzzle explores a g [ ... ]


Sharpen Your Coding Skills
Self-Descriptive Arrays

Put on your thinking cap for another set of conundrums that will exercise your coding skills. This time Melvin Frammis introduces his junior partner Bugsy Cottman to some classic number puzzles that c [ ... ]


Other Articles


<ASIN:059680279X>

<ASIN:0470526912>

<ASIN:1590597273>

<ASIN:0596806752>



Last Updated ( Friday, 16 December 2011 )