以下 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 编译器。
以下 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 编译器。
因为-0.0 == 0.0
和因此-0.0 >= 0.0
是真的。
使用fabs
(或fabsf
用于 float 而不是double
)而不是试图重新发明它。
用来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 具有完全相同的位表示形式,它们也不会在数字上 (==) 比较为相等。
-0 是二进制表示的产物,0 带有符号位设置。如果您想了解更多详细信息,维基百科有一篇关于签名零的综合文章。
正如人们上面所说的那样使用 fabs() 。如果您真的真的很想内联,请链接您的比较:
内联浮点 abs(float a) { return (a > 0.f) ?a : ( (a < 0.f) ? -a : 0); }