Unary and Negation Operators Part 2 – Numbers and Booleans

Hi again! Now, last I spoke (er… wrote) I had been going ad nauseum regarding the affects of unary and negation operators on strings. Today, I’ll be focusing my efforts with regards to these same operators but on a few of the remaining objects on the list: booleans and numbers… The others I’ll handle in future posts.

So, Unary and Negation Operators (which I’ll call UNOs for short) yield interesting results when combined with other JavaScript object types. We dealt with strings and the effects of UNOs on them in my last post; so as numbers will be relatively simple I’ll just blitz through this part…

+5 == 5
-5 == -5
-(-5) == 5

Well… Surprise, surprise… The plus and minus do the exact expected thing one would expect in standard mathematics…

The only exception to this is --5. --5 actually won’t evaluate as the -- operator is reserved for pre-decrement and post-decrement of variables, and not numbers… For the negation of a negative number parentheses need to be used, as per my last example.

And that’s UNOs with numbers… I told you it’d be quick…

Now we get to the interesting parts. Let’s start with booleans…

+false == 0
+true == 1


Okay, to understand why coercing false to a number results in zero, and why true is coerced to 1, I need to get into truthy and falsy values… Truthy and falsy values have the following traits:

  • Truthy values will coerce to true when converted to a Boolean. Examples of truthy values are all natural numbers both positive and negative (excluding zero), and non-empty strings, and all empty and non-empty arrays and objects. Basically any value that has definition, is not null, or zero, or empty qualifies as a truthy value (…and empty objects and arrays, I wish someone can explain this to me… That’s just plain weird). True as well counts as a truthy value.
  • Falsy values will coerce to false when converted to a Boolean. Examples of falsy values are zero, empty strings; null, NaN (Not a Number) and undefined. Naturally, false also counts as a falsy value.

So how do you test whether a value is truthy or falsy? You know how they say “two wrongs don’t make a right”? JavaScript have taken this concept and twisted it on its head. JavaScript’s Logical NOT operator (!) converts true to false and vice versa… So combining two of them you have a falsy/truthy operator which is capable of taking any value and determining if it is truthy or falsy. !! spits out true for truthy values and false for falsy values. It really is that easy.

So where am I leading with this? If you’ve been programming for a while, you’ll have come across similar examples of truthy and falsy values at work, probably without you realizing it:

var x=10;
while(x){
   f(); x--;
}

The while loop and the for loop are notorious for abusing the concepts of truthy and falsy values. See that solitary x in our example here? As you will know while loops work off a condition being satisfied to continue running. When the condition is no longer met, the while loop terminates and the code moves on. With each iteration the value of x decreases until it reaches zero. Once it does, the while loop finally converts zero to false and terminates. Similarly, you may have seen the following:

while(true) 

or

while(1)

Both statements mean the same thing… So, it would make sense that true and 1 are considered equivalent to one another logically. In fact, if you were to evaluate !!1 you would naturally get true, and evaluating +true will give you 1. Similarly, because zero is a falsy value you could conclude that !!0 would give you false, and therefore +false would give you 0.

And you’d be right…

Because 0 and 1 are falsy and truthy respectively they can technically be used as shortcuts for false and true respectively. While technically any number or truthy value could be used as a substitute for true, 1 is the simplest and quickest way. This little trick of using 0 and 1 as substitutes for false and true is often used in code golf (which I will cover in a later post) to conserve character usage. Basically, you’re saving 4 and 3 characters respectively.

So as a result:

+false == 0

and

+true == 1

In my next post, I will be addressing arrays and objects and how they react with UNOs. Stay tuned.

Unary and Negation Operators Part 1 – Strings

In my most recent post, I mentioned the various objects that exist in JavaScript, and the operators most commonly responsible for coercing one object type into another.

In this post, I’ll be focusing on the Unary Operator (+) and the Negation Operator ()

+"5" == +(5) == 5

In the above example we see the unary operator acting upon the “5” string resulting in said string being coerced into a number, naturally, the number 5.

Let’s take a look at the process as it happens:

  1. The unary operator upon first encountering the string, checks the nature of the string. In this case, it’s a string which is numeric by nature.
  2. Next, the unary operator coerces the string into its respective number. Note in this case, I’ve placed the 5 in parentheses to show that the 5 has still yet to be further acted upon. This will come into importance in later examples.
  3. Finally the unary operator acts upon the numeric 5 and coerces further with its secondary function, acting as a positive on the numeric 5 we have already coerced from the string. The final result is an unsigned (and thus naturally positive) 5.

Let’s go a step further, now this time with the Negation Operator, the sign.

-"5" == -(5) == -5

In this example we see the negation operator acting upon the “5” string resulting in said string being coerced into a number, in this case, the number -5.

So let’s see what happens this time around:

  1. The negation operator upon first encountering the string, checks the nature of the string. As with the previous example, it’s a string which is numeric by nature.
  2. Next, the negation operator coerces the string into its respective number. Note as with the previous example, I’ve also placed the 5 in parentheses to show that the 5 has still yet to be further acted upon.
  3. Finally the negation operator acts upon the numeric 5 and coerces further with its secondary function, acting as a negator on the numeric 5 we have already coerced from the string. The final result is -5.

If we were to have used the string “-5” instead in these two examples we would get -5 and 5 respectively. Why? Let’s take a quick look.

+"-5" == +(-5) == -5

-“-5” == -(-5) == +5 == 5

So, once the -5 is “cast out” (the supposed technical term for the conversion of one object type into another) from the string, the unary or negation operator performs the respective mathematical operation on the -5 to convert it to -5 or 5 respectively.

So, where does that leave us? Sure, we can cast out numbers until we’re blue in the face. But what about other kinds of strings, what about arrays, objects, dates, booleans? Could we cast out a number from a function?

The answer is yestechnically. What if we had a string that had a combination of letters and numbers, or starting with a number, or numbers at the end, or no numbers at all? Would an empty string cast out?

I’ve taken the liberty of doing these for you. I’ve shown the result after the “//” in each example. Let’s start with strings:

+"7 monkeys" // NaN

NaN means “Not a Number”, even though typeof(+”7 monkeys”) yields “number”, so apparently “Not a Number” is still a number…? Generally +x should for all intensive purposes yield “number”, but because “7 monkeys” or any similar string cannot be completely coerced into a number, Not a Number results. Strangely though, parseInt(“7 monkeys”) and parseFloat(“7 monkeys”) both yield 7. I will talk about these functions in a later post.

-"7 Monkeys" // also yields NaN
+"3+3" // NaN

The above example threw me at first, after all, with +”3+3″ one would think the unary operator would evaluate the string and return 6… Not so. Unary and Negation operators DO NOT evaluate the contents of a string, in fact they don’t evaluate anything. Unary and Negation operators will only do the following:

  • A unary or negation operator will first coerce the object used against the operator to a number based on the content of the object.
  • If the unary operator is used, the system will then work out the resulting number based on standard mathematical rules based on placing a positive sign in front of it.
  • If the negation operator is used, the system will then work out the resulting number based on standard mathematical rules based on placing a negative sign in front of it.
  • Unary and Negation operators will work only on strings that are formatted as recognized numbers within JavaScript.

Note that last point… For a string to be correctly coerced to a number, the initial string has to be formatted like a JavaScript number.

Generally a JavaScript number is formatted in one of three ways:

  • ±A (where A represents a series of integers (containing 1 or more digits)
  • ±A.B (where A and B represent two series of integers (containing 1 or more digits) on either side of the decimal point
  • ±A.Be±C (where A, B and C represent three series of integers (containing 1 or more digits), and e (or E) represents the 10C exponential function. Technically this will be the same as ±A.B × 10±C. So, for example, 7.56e3 = 7.56 × 103 = 7.56 × 1000 = 7560, and 4.2e-2 = 4.2 × 10-2 = 4.2 × 0.01 = 0.042.

One exception to the rule is that a number in JavaScript can be represented with a decimal point but nothing following it. So, +”7.” will coerce into 7, and +”7.e2″ will coerce to 700. but +”7.e2.3″ will render out as a Syntax Error due to the fact that the exponential needs to be an integer, and not in this case, 2.3.

+”foo” // NaN

In the conversion of a string to a number, if the number does not match the conventional JavaScript number formats I mentioned earlier, the only other alternative is for it to render out as Not a Number (NaN).

I will provide further insight into these operators and their interactions with other JavaScript object types in my next post.