如何在C中将负零转换为正零?

Guz*_*Guz 16 c floating-point

您好我正在学习Objective C,而我正在做经典的计算器示例.

问题是当我将零乘以任何负数时,我得到负零,并且我将结果放入(双)类型!

为了看看发生了什么,我玩了调试器,这就是我得到的:

(gdb)print -2*0
$ 1 = 0

(gdb)print(double)-2*0
$ 2 = -0

在第二种情况下,当我将它转换为双重类型时,它变成负零!如何在我的应用程序中修复它?我需要和双打一起工作.如何修复结果,以便在结果为零时得到零?

Ric*_*III 13

我做了一个简单的测试:

double d = (double) -2.0 * 0;

if (d < 0)
    printf("d is less than zero\n");
if (d == 0)
    printf("d is equal to zero\n");
if (d > 0)
    printf("d is greater than zero\n");

printf("d is: %lf\n", d);
Run Code Online (Sandbox Code Playgroud)

它输出:

d等于零
d是:-0.000000

因此,要解决此问题,您可以向应用程序添加简单的if-check:

if (d == 0) d = 0;
Run Code Online (Sandbox Code Playgroud)

  • 如果你有一个C99实现(`if(signbit(d))d*= -1;或者使用[signbit()](http://pubs.opengroup.org/onlinepubs/9699919799/functions/signbit.html). ). (6认同)
  • `if(d == 0)d = 0;`...并不总是有效,至少在Visual Studio 2008上是这样. (2认同)

Ara*_*yan 5

http://en.wikipedia.org/wiki/Signed_zero

数字0通常编码为+0,但可以用+0或-0表示

它不应该影响计算或UI输出.

  • `-0.0` 会影响特定情况下的数值计算:[+0.0 和 -0.0 上的哪些运算和函数会产生不同的算术结果?](/sf/ask/1773249341/) (2认同)

chq*_*lie 5

这里有一个关于运算符优先级的误解:

(double) -2 * 0
Run Code Online (Sandbox Code Playgroud)

被解析为

((double)(-(2))) * 0
Run Code Online (Sandbox Code Playgroud)

这与(-2.0) * 0.0.

C 标准信息性附录 J 将某些运算符是否可以生成负零以及负零是否在存储在对象中时成为正常零列出为 Unspecifier 行为(6.2.6.2)。

相反,(double)(-2 * 0)0.0在大多数当前平台上生成正零,因为乘法是使用整数算法执行的。C 标准确实支持区分正零整数和负零整数的体系结构,但这些在当今已经非常罕见。

如果你想强制零为正,这个简单的修复应该有效:

if (d == 0) {
    d = 0;
}
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式使意图更清晰:

if (d == -0.0) {
    d = +0.0;
}
Run Code Online (Sandbox Code Playgroud)

但是如果d是正零,测试也会成功。

Chux 为符合 IEC 60559 的环境提供了更简单的解决方案:

d = d + 0.0;  // turn -0.0 to +0.0
Run Code Online (Sandbox Code Playgroud)

  • 一般来说,这是正确的,但在这种特殊情况下,您想检查 `d` 是否正好是 `0.0` 或 `-0.0`,这与 `==` 运算符无法区分。与“-DBL_EPSILON”相比是不正确的,因为您会将许多小的负非零值转换为“0.0”。 (2认同)