How to get a -0 result in floating point calculations and distinguish it from +0 in C#?

只愿长相守 提交于 2019-11-30 21:18:42

Here is a practical example of differentiating between the two without examining the bits. MSDN links here and here assisted me in constructing this example.

static void Main(string[] args)
{
    float a = 5 / float.NegativeInfinity;
    float b = 5 / float.PositiveInfinity;
    float c = 1 / a;
    float d = 1 / b;
    Console.WriteLine(a);
    Console.WriteLine(b);
    Console.WriteLine(c);
    Console.WriteLine(d);
}

Output:

0
0
-Infinity
Infinity

Take note that -0 and 0 both look the same for comparisons, output, etc. But if you divide 1 by them, you get a -Infinity or Infinity, depending on which zero you have.

Negative zero is to do with the way that the number is stored in binary, not any real achievable result from a mathematical calculation.

In floating point storage, the topmost bit is often used to denote sign. This leaves 31 bits for data (in a 32bit floating point value) so there are actually two representations for zero.

00000000 00000000 00000000 00000000
Or
00000000 00000000 00000000 00000001

Both represent zero, but one with the sign bit set to negative.

Naturally, this would normally occur when you incremented the highest possible positive number, it would overflow back to negative zero.

In .net however I think by default the type does overflow checks and will throw an exception rather than let you overflow, so the only way to really archive this value is by setting it directly. Also, -0 should always compare equal to +0.

There is more about it on Wikipeida

One way is to use the BitConverter.GetBytes. If you check the bytes, you will see that the sign bit for the value is actually set indicating that its negative.

byte[] zeroBytes = BitConverter.GetBytes(zero);
byte[] negZeroBytes = BitConverter.GetBytes(negZero);

bool sameBytes = zeroBytes[7] == negZeroBytes[7];

Try this. If pz is positive zero and nz is negative zero:

Double.PositiveInfinity/pz => Double.PositiveInfinity
Double.PositiveInfinity/nz => Double.NegativeInfinity

I got this from ECMA C# specification.

You can obtain negative zero by dividing any positive number by negative infinity:

10.0/Double.NegativeInfinity

After checking, I see that -1.0 / double.PositiveInfinity does return -0. Indeed, 1.0 / (-1.0 / double.PositiveInfinity) returns -infinity.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!