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

发布于 2024-07-25 15:54:42 字数 147 浏览 12 评论 0原文

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

The MSDN documentation mentions that double type includes negative zero. However, both -1.0 / double.PositiveInfinity and -double.Epsilon / 2 appear to return normal 0 (and compare equal to it). How can I get -0?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

暗恋未遂 2024-08-01 15:54:42

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

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.

〗斷ホ乔殘χμё〖 2024-08-01 15:54:42

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

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

00000000 00000000 00000000 00000000
或者
00000000 00000000 00000000 00000001

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

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

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

Wikipeida 上有更多相关信息

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

找回味觉 2024-08-01 15:54:42

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

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

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

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];
羁拥 2024-08-01 15:54:42

尝试这个。 如果 pz 是正零并且 nz 是负零:

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

我从 ECMA C# 规范

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

10.0/Double.NegativeInfinity

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
み青杉依旧 2024-08-01 15:54:42

检查后,我发现 -1.0 / double.PositiveInfinity 确实返回-0。 事实上,1.0 / (-1.0 / double.PositiveInfinity) 返回-infinity

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文