5

以下 abs 函数有时会返回-0 (减零)

inline float abs(float a){
    return( a>=0.0f? a :-a);
}

更具体地说,该语句 sprintf(str, "%.2f", abs(-0.00f) );产生“-0.00”,这很烦人,因为字符串显示给用户。

问题:

1)为什么会产生-0

2)如何解决?

PS:我正在使用 xcode 的(目标)c 编译器。

4

3 回答 3

12
  1. 因为-0.0 == 0.0和因此-0.0 >= 0.0是真的。

  2. 使用fabs(或fabsf用于 float 而不是double)而不是试图重新发明它。

于 2013-07-12T17:15:09.613 回答
2

用来signbit()区分。适用于 -0 和 -INF 以及我认为 -NAN (如果有这样的事情)。

// C11
inline float ragnarius_abs(float a) {
  return signbit(a) ? -a : a;
}

至于为什么a = -0.0f; a>=0.0f? a :-a;产生-0
-0.0f >= 0.0f为真:-0.0f并且0.0f两者在数值上相等,因此a-0.0f返回。


关于浮点类型的进一步说明:

-0 等于 0。这是唯一的浮点异常,其中 2 个不同的二进制 IEEE 754 位表示比较相等。其他一些浮点格式具有表示相同数值的各种不同位表示。

NAN 不等于 NAN。NAN 可以用多种表示形式表示,但即使 2 个 NAN 具有完全相同的位表示形式,它们也不会在数字上 (==) 比较为相等。

于 2013-07-12T18:18:50.027 回答
2
  1. -0 是二进制表示的产物,0 带有符号位设置。如果您想了解更多详细信息,维基百科有一篇关于签名零的综合文章。

  2. 正如人们上面所说的那样使用 fabs() 。如果您真的真的很想内联,请链接您的比较:

    内联浮点 abs(float a) { return (a > 0.f) ?a : ( (a < 0.f) ? -a : 0); }

于 2013-07-12T21:20:58.647 回答