# What's the difference between 0 and -0?

My daughter's math lessons this year have included the concept of negative numbers (that is, numbers that are less than zero, not numbers that have a bad attitude). She has used number lines such as this one to help her while she completes her homework:

Notice that in this number line, there is no -0. But there is a -0 in SAS (and in many other programming languages). It's a bit elusive, but still easier to find than a Higgs boson particle.

Here is one way to tease it out:

```data neg0; a= 1 * 0; /* this is 0 */ b= -1 * 0; /* is it 0? */ put a= b=; run;```

The default formatted output hides the negative nature of the "nothing" we put in the variable b.

```a=0 b=0
```

But by applying a hexadecimal format, we can take a closer look at the variable's raw value:

```data neg0; a= 1 * 0; b= -1 * 0; put "a=0x" a:hex16." b=0x" b:hex16.; run;```

Now look at the result:

```a=0x0000000000000000  b=0x8000000000000000
```

You can see that there is just one bit of difference (literally!) between the two numbers. But would you ever notice this? Certainly not if you perform an equality test:

```data work.neg0; a= 1 * 0; b= -1 * 0; put "Is 0x" a:hex16. "equal to 0x" b:hex16. "?"; if (a eq b) then put "EQUAL!"; else put "NOT EQUAL!"; run;```

This program yields a deceiving result:

```Is 0x0000000000000000 equal to 0x8000000000000000 ?
EQUAL!
```

So what's happening? Is SAS broken? Or is there a hole ripped in the fabric of reality?

No, it's okay! This is all part of the IEEE 754 standard for floating point arithmetic. From the Wikipedia entry for "Signed zero":

The IEEE 754 standard for floating point arithmetic (presently used by most computers and programming languages that support floating point numbers) requires both +0 and −0.

In all but a few special cases, -0 behaves just like 0. Whew! That's a relief.

(Are you interested in learning more about "nothing"? I highly recommend the book Zero: The Biography of a Dangerous Idea by Charles Seife.)

1. Chris Hemedinger
Posted December 15, 2011 at 10:30 am | Permalink

You can make this play up in other languages as well, but you might need a different approach. Here is a C# version that performs the trick with the Ceiling function:

``` static void Main(string[] args)
{
double a = Math.Ceiling(-0.1);
double b = 1 * 0;
double c = -1 * 0;
Console.WriteLine("a = Math.Ceiling(-0.1), a=" + a.ToString());

byte[] bytes;
bytes = BitConverter.GetBytes(a);
Console.WriteLine("Bytes of a:");
Console.WriteLine(BitConverter.ToString(bytes));

Console.WriteLine("b = 1 * 0, b=" + b.ToString());
bytes = BitConverter.GetBytes(b);
Console.WriteLine("Bytes of b:");
Console.WriteLine(BitConverter.ToString(bytes));

Console.WriteLine("c = -1 * 0, c=" + c.ToString());
bytes = BitConverter.GetBytes(c);
Console.WriteLine("Bytes of c:");
Console.WriteLine(BitConverter.ToString(bytes));
}
```

Output:

```a = Math.Ceiling(-0.1), a=0
Bytes of a:
00-00-00-00-00-00-00-80
b = 1 * 0, b=0
Bytes of b:
00-00-00-00-00-00-00-00
c = -1 * 0, c=0
Bytes of c:
00-00-00-00-00-00-00-00
```
2. Tom Kari
Posted December 17, 2011 at 10:59 pm | Permalink

Oh my goodness, Chris! "numbers less than zero, not numbers that have a bad attitude"? Groan!!

However, congratulations on the rest of the post. That's a piece of computing I've never seen before!

Amazing the funny little corners that this business has.

Tom

• Chris Hemedinger
Posted December 19, 2011 at 10:55 am | Permalink

Thanks Tom! I'm thinking that this expression could catch on in Ottawa to describe the weather.

"Oh sure, the meteorologist says we'll have a high of zero today, but with the wind chill, it feels like negative zero."

1. By Numerical precision in SAS on March 1, 2012 at 2:12 pm

[...] calculations, we must then dust off our lesson about floating-point math. We cite IEEE standards. As we've seen in this blog, floating-point nuances are good for "stupid math tricks", but they can also cause confusion when [...]