如何在浮点计算中获得-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
。