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=;

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.;

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!";

This program yields a deceiving result:

Is 0x0000000000000000 equal to 0x8000000000000000 ?

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 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("b = 1 * 0, b=" + b.ToString());
         bytes = BitConverter.GetBytes(b);
         Console.WriteLine("Bytes of b:");
         Console.WriteLine("c = -1 * 0, c=" + c.ToString());
         bytes = BitConverter.GetBytes(c);
         Console.WriteLine("Bytes of c:");


    a = Math.Ceiling(-0.1), a=0
    Bytes of a:
    b = 1 * 0, b=0
    Bytes of b:
    c = -1 * 0, c=0
    Bytes of c:
  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.


    • Chris Hemedinger 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."

  3. Posted December 8, 2016 at 7:50 am | Permalink

    This post was really helped us to solve an initially baffling problem.We use a macro to calculate a check sum on the *contents* of SAS datasets in order to be able to identify the datasets when we transfer them via SAS V5 transport format. The transport file is sent along with the check sum and the recipient extracts the dataset, re-calculates the check sum and compares to the original. We were getting differences where there should have been none. It turned out that the difference were negative zeros which were converted to positive when creating the SAS V5 transport file because this uses an IBM standard for numbers.

    • Chris Hemedinger Chris Hemedinger
      Posted December 8, 2016 at 8:27 am | Permalink

      Wow, that's an unintended side effect...but glad it helped!

One Trackback

  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 [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>