MSDN 文档提到该double
类型包括负零。但是,两者-1.0 / double.PositiveInfinity
和-double.Epsilon / 2
似乎都返回正常的 0 (并且比较等于它)。我怎样才能得到-0?
5 回答
这是一个在不检查位的情况下区分两者的实际示例。此处和此处的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 中,我认为默认情况下该类型会进行溢出检查,并且会抛出异常而不是让您溢出,因此真正存档此值的唯一方法是直接设置它。此外,-0 应该始终等于 +0。
维基百科上有更多关于它的信息
一种方法是使用 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
。