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

## 5 Comments

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:

Output:

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

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

negativezero."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.

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

## One Trackback

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