Check out a free preview of the full Deep JavaScript Foundations, v3 course:
The "Negative Zero" Lesson is part of the full, Deep JavaScript Foundations, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle gives the context of -0 in JavaScript and explains how operations on it can cause unexpected results.

Get Unlimited Access Now

Transcript from the "Negative Zero" Lesson

[00:00:00]
>> Kyle Simpson: Let's talk about another special value. This one seems rather strange because what on Earth is a negative zero? If you ask a mathematician, they'll say that's made up, that doesn't exist, that's not a real thing. It definitely exists in programming, it definitely exists in IEEE 754. Just like nan exists in IEEE 754, but a mathematician doesn't know what nan means.

[00:00:25] Then it definitely also requires, IEEE 54 if you will, requires there to be a negative zero. So, what does that mean? Well, it's essentially the zero value, but with the sign bit on. So it is the negative representation of a zero. Now, early days of JavaScript felt that JavaScript developers would never want a negative zero.

[00:00:50] And so they actually went to extreme lengths to try to pretend as if it didn't exist which we're gonna see a whole bunch of weirdness. For example, if I have a -0 assigned to trendRate line 1, here and I triple equals it with -0 I get true, sounds great.

[00:01:09] What happens if I stringify it? I'll use the toString method here, there's other ways, but if I stringify it, I get 0. That's not good, right? 0, where's my negative sign? The early incantation of JavaScript felt like JavaScript developers would think that it was a bug if you took a -0 and stringified it and got -0 in the string.

[00:01:33] It felt like that would look to the end user like a bug, and JavaScript would get blamed. I think in retrospect, languages should do the correct thing and it's on developers to do something that's reasonable to users. Languages should not step in and try to second guess their developers.

[00:01:50] And there's a bunch of the historical weirdness in JavaScript where they tried for various reasons to be more palatable. We get automatic semi colon insertion and a whole, whole host of other things where the language trying to out smart the developer. And it turns out don't out smart the developer.

[00:02:08] Just let them do what they can with the sensible reasonable coherent set of tools, okay? Okay, so the two string lies to us and by the way, the triple equals also lies to us, cuz it says the -0 is equal to a 0. And in also -0 is neither less than 0 or greater than 0.

[00:02:27] So, the less than and the less than or equal and the greater, I'm sorry, the less than and a greater than specifically, they lie
>> Kyle Simpson: They all lie. So for a long time we didn't really have a built in way of determining if we had a -0, you could get -0s, but you couldn't determine that you had one.

[00:02:46] Until ES6 they added a utility called object.is, object.is, I like to refer to this as like the quadruple equals. People like to joke about how double equals, it allows all these different coercions and stuff we'll get into a course of a quality in bit. They like to joke about double equals is changing and triple equals is exact, it's strict except for a couple of lies.

[00:03:11] Well, if we don't want those lies let's just add another equals on, so it's like the fourth equals here. It doesn't lie at all, if it's a -0, if it's true and otherwise, it doesn't. And if it's a zero, it gives you true or otherwise, I mean, false or otherwise it doesn't.

[00:03:26] So that's your only option, if you wanna test for the zero. Actually, there's technically a mathematical operation and that's a hint for later. There is a mathematical operation that you can use to determine -0. But for the most part, the best way to do this is to use this built-in checker and by the way, object.is can be used to check names.

[00:03:47] Although I would say number.is is a more semantic tool for it, but you can also use object.is. So now you're asking yourself, okay great, there's this weird nuanced thing that no one cares about, right? Who would even care about a negative zero? Well, I think they are legitimate purposes, I have actually use negative zeros in my programs before.

[00:04:07] Mathematically it's very common for us to refer to two separate entities or two separates characteristics in the same numeric value. For example, the absolute value of the number represents for example how fast something might be moving. And the sign represents what direction it's moving. Say you've got a little car on a map and this is actually what I had.

[00:04:30] I worked in a company where we built this mapping solution, and we had this little car that moved around a map. And I needed to know whether the car was moving this way or this way. What direction do I make it look when it stops? Well, I wanted to make it look in the same direction that it was before it stopped.

[00:04:48] How do I determine what one number, what direction it was, if at zero, we lose the sign? So negative zero was actually useful there, and I use those in games for very similar purposes. So our trendRate, as the going example goes, is that I could use the sign of this number, there's a utility called math.sign, which is supposedly gonna tell us is this thing doesn't have the sign bit or not.

[00:05:15] And that should have been able to tell us if we had a negative zero. Unfortunately, that went and did something super dumb which was that they made math.sign return negative zero and zero instead of negative one and one. So you can't really use Math.sign to determine this. But if you wanted to make your own, here I'm making my own by basically fixing up the sign method.

[00:05:37] And I'm checking if, on one of the two 0s, that's what happens on line 8. And on one of the two 0s, if I'm not one of the two 0srather than I can use the sign. If I'm one of the two zeros, I need to use object.is to figure out if I'm a -0.

[00:05:54] So that fixed up sign method, you'll notice down there in line 13, it returns a -1 when there's a -0. So yet another way that it might be useful for us to have a sign method that actually works, and here's a way that we can make a sign method that works in a useful way.

[00:06:12] There's some reason for the -0 thing in their return value, but I don't think it's very useful. Okay, so the trend example as I said. The trend example, if I wanted to keep track of what direction something was moving. Like if this was a stock or something like that and I wanted to keep track of, even if it's at zero has it been falling or has it been going up?

[00:06:34] And I wanna show whether it's been falling or rising in it's stock price for example. Where here you notice that even if I track a negative zero I can show that it's been falling at that point. As opposed to being rising when it gets at the zero value.

[00:06:50] So, negative zeros even though they seem like they may be a little bit nuanced, they're a value that exist in the language so, you should know about them and know how to test for them. And now that you know that they exist, you might even be able to find uses for them.

[00:07:05]
>> Student: For me it's not that, it's still hard for me, and I would rather define direction versus. For me it's hard there is no math value. I mean, zero zero right, it's a language that supports it.
>> Kyle Simpson: Yeah, I understand that perspective and that's entirely valid, but that's sounds to me like when somebody says I don't care about negative numbers at all.

[00:07:31] I just have numbers that have absolute values, I used unsigned integers or something. Signed numbers are a thing and there a thing in math, so if there's a thing in math then a negative zero is also a thing that can be useful. Okay, so those special values, they're gonna occur in our programs, and having an acute awareness of types and the values that can exist in our programs.

[00:07:58] They're gonna help us not only avoid bugs, but also make better usage of our tool. Not only just be able to do something, but maybe do something more semantically, maybe make something that makes our code more readable or more understandable. I would argue that it is much more consistent if I'm using positive or negative in my regular numbers to indicate direction, that I'll not have separate variable to track zeros direction.

[00:08:23] It's much more consistent to me, and I think more communicative in code, if I use the sign of the zero to also indicate the direction.