如何在浮点计算中获得-0结果并将其与C#中的+0区分开来?

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

这是一个在不检查位的情况下区分两者的实际示例。 这里和这里的 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,具体取决于您具有的零。

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

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

00000000 00000000 00000000 00000000
要么
00000000 00000000 00000000 00000001

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

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

但是在.net中我认为默认情况下类型会执行溢出检查并抛出exception而不是让你溢出,所以真正归档这个值的唯一方法就是直接设置它。 此外,-0应始终比较等于+0。

Wikipeida上有更多关于它的内容

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

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

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

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

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

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

 10.0/Double.NegativeInfinity 

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