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;
这里有关于运算符优先级的误解:
(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。