6

MSDN 文档提到该double类型包括负零。但是,两者-1.0 / double.PositiveInfinity-double.Epsilon / 2似乎都返回正常的 0 (并且比较等于它)。我怎样才能得到-0?

4

5 回答 5

16

这是一个在不检查位的情况下区分两者的实际示例。此处此处的MSDN 链接帮助我构建了此示例。

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);
}

输出:

0
0
-Infinity
Infinity

请注意,-0 和 0 在比较、输出等方面看起来都是一样的。但是如果将 1 除以它们,则会得到 -Infinity 或 Infinity,具体取决于您拥有的零。

于 2009-06-25T13:25:17.363 回答
3

负零与数字以二进制存储的方式有关,而不是数学计算的任何实际可实现的结果。

在浮点存储中,最高位通常用于表示符号。这为数据留下了 31 位(在 32 位浮点值中),因此实际上有两种表示为零。

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001

两者都表示零,但符号位设置为负。

自然,这通常会在您增加可能的最大正数时发生,它会溢出回负零。

但是,在.net 中,我认为默认情况下该类型会进行溢出检查,并且会抛出异常而不是让您溢出,因此真正存档此值的唯一方法是直接设置它。此外,-0 应该始终等于 +0。

维基百科上有更多关于它的信息

于 2009-06-25T13:21:26.357 回答
2

一种方法是使用 BitConverter.GetBytes。如果您检查字节,您将看到该值的符号位实际上已设置,表明其为负。

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

bool sameBytes = zeroBytes[7] == negZeroBytes[7];
于 2009-06-25T13:21:02.690 回答
2

试试这个。如果pz为正零且nz为负零:

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

我从ECMA C# 规范中得到了这个。

您可以通过将任何正数除以负无穷来获得负零:

10.0/Double.NegativeInfinity
于 2009-06-25T13:26:03.197 回答
0

检查后,我看到-1.0 / double.PositiveInfinity 确实返回-0。确实,1.0 / (-1.0 / double.PositiveInfinity)回报-infinity

于 2009-06-25T13:31:51.640 回答