C中的负零

你好我正在学习Objective C,我正在做经典的计算器示例。

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

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

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

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

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

提前致谢。

我做了一个简单的测试:

 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); 

它输出:

d等于零
d是:-0.000000

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

 if (d == 0) d = 0; 

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

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

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

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

 (double) -2 * 0 

被解析为

 ((double)(-(2))) * 0 

这基本上与(-2.0) * 0.0

C标准信息附件J列为非指定行为某些运算符是否可以生成负零,以及当存储在对象中时负零是否变为正常零(6.2.6.2)。

相反, (double)(-2 * 0)应该在大多数当前平台上生成正零0.0 ,因为乘法是使用整数运算执行的。 C标准确实支持区分正负零整数的架构,但现在这些架构很少见。

如果你想强制零是积极的,这个简单的修复应该工作:

 if (d == 0) { d = 0; } 

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

 if (d == -0.0) { d = +0.0; } 

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

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

 d = d + 0.0; // turn -0.0 to +0.0 

如何在我的应用程序中修复它?

代码确实没有被破坏,所以没有什么需要“修复”。 @kennytm

如何修复结果,以便在结果为零时得到零?

为了轻松摆脱-当结果是-0.0 ,加上0.0 。 遵循标准(IEC 60559浮点)规则的代码将产生丢弃-符号。

 double nzero = -0.0; printf("%f\n", nzero); printf("%f\n", nzero + 0.0); printf("%f\n", fabs(nzero)); // This has a side effect of changing all negative values // pedantic code using  if (signbit(nzero)) nzero = 0.0; // This has a side effect of changing all negative values printf("%f\n", nzero); 

通常的输出。

 -0.000000 0.000000 0.000000 0.000000 

然而对于可能具有任何价值的一般double x ,难以击败以下。 @Richard J. Ross III @chqrlie x + 0.0方法的优势在于可能没有引入分支,但以下内容很清楚。

 if (x == 0.0) x = 0.0; 

注意: fmax(-0.0, 0.0)可能产生-0.0。