-0 is mostly useless

-0 is mostly useless

Negative zero is defined in the IEEE 754 standard and every programming language that needs to comply with the standard implements it.

However, -0 and +0 (written 0 by default) are equivalent. This makes sense because -0 is neither greater nor less than 0, so it has no choice but to be equal.

Programming gurus claim that you need to use -0 whenever it makes sense but don’t give any reason why you should use it. Considering that -0 is so easily mistaken with +0, wouldn’t this give rise to hard to find bugs?

In this post, I’ll show you why -0 should be avoided and what to do instead.

Detecting negative zero is not straightforward

Take a look at this:

1 == 1
1 == 2

The first statement returns True while the second, False. Using this simple knowledge, we can construct code such as this:

if speed > 0:
    print("Car is moving")
else:
    print("Car has stopped")

Instead of recording only the speed of a car, we can also encode its direction in the same variable:

if speed < 0:
    direction = "left"
else:
    direction = "right"

But what happens when the car is facing left and is also stopped? Naturally, the value of speed should be -0. However, in the above logic, direction would be right because -0 < 0 is False. And so a bug lies in our code.

We fix it by introducing some extra logic:

import math

if speed == 0:
    is_negative = math.copysign(1.0, 0.0) < 0

    if is_negative:
        direction = "left"
    else:
        direction = "right"
elif speed < 0:
    direction = "left"
else:
    direction = "right"

The bug has now been fixed but this code isn’t as readable as it should be.

Using an object instead

Instead of using the sign to encode direction, why not use use a field in your object?

class Car:

    def __init__(self, speed=0, direction="right"):
        self.speed = 0
        self.direction = direction

This code is much easier to read and will likely introduce less bugs.

Performance nuts will claim that this code will take more memory and is not correct. How much more memory exactly?

Instances of the Car class will require 48 bytes of memory while ints require at most 36 bytes. In some severely memory constrained environments, encoding direction in the int itself makes sense but is Python a good language for such a situation? Most sane engineers would opt for assembly or C if working memory is severely limited.

Conslusion

As you can see, making use of -0 is only good for pumping your own ego and introduce subtle hard to find bugs in your code.

Instead, make use of OOP because its purpose is to allow developers to model state clearly and intuitively.