# Why does !!1=="1" equal true and !!2=="2" equal false?

Javascript## Javascript Problem Overview

As the title states, why does:

```
> !!1=="1"
```

equal

```
True
```

and

```
> !!2=="2"
```

equal:

```
False
```

Likewise, why does `> "1"==true`

equal `true`

and `> "2"==true`

equal `false`

I'm baffled. Are these just bugs in JS or what's going on here?

## Javascript Solutions

## Solution 1 - Javascript

As per the Operator precedence rules, logical `!`

has higher priority over `==`

. So, in both the cases, `!!`

is evaluated first.

**Note:** Truthiness of various objects have been explained in this answer of mine.

##### First Case

```
!!1 == "1"
```

`!1`

will be evaluated to `false`

, since `1`

is considered Truthy. Negating again we get `true`

. So the expression becomes

```
true == "1"
```

Now, the coercion rules kick in as you have used `==`

operator, which evaluates as per the The Abstract Equality Comparison Algorithm defined in ECMAScript 5.1 Specification,

> 6. If `Type(x)`

is `Boolean`

, return the result of the comparison `ToNumber(x) == y`

.

So, `true`

will be converted to a number, which is 1 as per `ToNumber`

algorithm for Boolean values. Now the expression becomes

```
1 == "1"
```

Now,

> 4. If `Type(x)`

is `Number`

and `Type(y)`

is `String`

,
return the result of the comparison `x == ToNumber(y)`

.

So, `"1"`

will be converted to a number and that will give 1, as per the `ToNumber`

algorithm. That is why it shows `true`

in the first case.

##### Second Case

The same rules are applied here.

```
!!2 == "2"
```

becomes

```
true == "2"
```

then

```
1 == "2"
```

which becomes

```
1 == 2
```

which is not `true`

, that is why the second case prints `false`

.

## Solution 2 - Javascript

tldr; this is due to the [ToNumber] conversions in the `==`

operator algorithm.

The first step is to simplify the expression. Since `!!x=="x"`

is parsed like `(!!x)=="x"`

and `!!a_truthy_expression -> true`

, the actual relevant expression for the equality is

```
!!1=="2" -> true=="1" -> Boolean==String
!!2=="2" -> true=="2" -> Boolean==String
```

So then looking at the rules for 11.9.3 The Abstract Equality Comparison Algorithm and following along with the application yields

> Rule 6 - If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.

which results in `Number==String`

or 1=="1" and 1=="2", respectively^{1}. Then the rule

> Rule 7 - If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).

is applied which results in `Number==Number`

or 1==1 and 1==2, respectively^{1}; the latter is clearly false.

> Rule 1 - If Type(x) is the same as Type(y), then [by c.iii.] If x is the same Number value as y, return true [else return false].

(The same algorithm explains the `String==Boolean`

case when the complementing rules are applied.)

^{1}To see the [ToNumber] rule applied, consider:

```
+false -> 0
+true -> 1
+"1" -> 1
+"2" -> 2
```

## Solution 3 - Javascript

**Its a precedence operator problem.**

The `!`

operator is an unary operator. That means the left side must be an expression or a boolean evaluable section. See Javascript MDN.

```
!!1==1 is not necessary !!(1==1)
!!2==2 is not necessary !!(2==2)
```

I think that these expressions should be consistent if the equal operator has more precedence than ! operator. But if we consider the opposite, evaluating first negations we have:

```
!!1 == 1
!1 -> false
!!1 -> true
!!1 == 1
```

And with the two

```
!!2==2
!2 -> false
!!2 -> true
(!!2) == 2 -> false
```

That is because the ! operator has precedence over == operator

## Solution 4 - Javascript

`!!1`

is equal to true, and "1" is equal to true ("0" is false, so is every other string). So `!!1 == "1"`

evaluates to `true == true`

, which of course returns true.

`!!2`

is also equal to true. As I mentioned earlier, "2" is not "1", so it's false. Therefore, we have `true == false`

, which of course returns false.

If you want to see if 2 (a number) is equal to "2" (a string representation of a number), then all you have to do is `2 == "2"`

, which evaluates to `2 == 2`

, which is true. The difference is that we're not comparing a boolean against a boolean. We're comparing a number against a number.

Basically, putting `!!`

in front of a number converts to a boolean, which forces JavaScript to cast your string to a boolean instead of a number.

## Solution 5 - Javascript

Because "1" may be considered as "true" when you do equality check, not identity, but "2" - can't.