您好,我正在学习Objective C,而我正在做经典的计算器示例。
问题是,当我将零乘以任何负数时,我得到负零,并且我将结果放入(双)类型!
为了看看发生了什么,我玩了调试器,这就是我得到的:
(gdb)print -2 * 0
$ 1 = 0(gdb)print(double)-2 * 0
$ 2 = -0
在第二种情况下,当我将其转换为双重类型时,它变为负零!如何在我的应用程序中修复它?我需要和双打一起工作。 如何修复结果,以便在结果为零时得到零?
答案 0 :(得分: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);
输出:
d等于零
d是:-0.000000
因此,要解决此问题,您可以向应用程序添加简单的if-check:
if (d == 0) d = 0;
答案 1 :(得分:5)
答案 2 :(得分:3)
这里存在关于运算符优先级的误解:
(double) -2 * 0
被解析为
((double)(-(2))) * 0
与(-2.0) * 0.0
基本相同。
C标准信息附件J列为非指定行为某些运算符是否可以生成负零,以及当存储在对象中时负零是否变为正常零( >
相反,(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
答案 3 :(得分:2)
如何在我的应用程序中解决这个问题?
代码确实没有被破坏,因此无需修复&#34;。 @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 <math.h>
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。
答案 4 :(得分:0)
在我的代码中(在C MPI intel编译器上)-0.0
和+0.0
不相同。
例如:
d = -0.0
if (d < 0.0)
do something...
它正在做这个“事情”。
还要添加-0.0 + 0.0 = -0.0...