abs和fabs有啥区别?
Posted
技术标签:
【中文标题】abs和fabs有啥区别?【英文标题】:What's the difference between abs and fabs?abs和fabs有什么区别? 【发布时间】:2015-11-16 15:07:48 【问题描述】:我在 python here 上检查了 abs
和 fabs
之间的区别
据我了解,速度和传递的类型存在一些差异,但我的问题与 V.S. 上的原生 c++ 相关
关于 V.S.
我在Visual Studio 2013 (v120)
上尝试了以下操作:
float f1= abs(-9.2); // f = 9.2
float f2= fabs(-9); // Compile error [*]
所以fabs(-9)
它会给我一个编译器错误,但是当我尝试执行以下操作时:
double i = -9;
float f2= fabs(i); // This will work fine
我从第一个代码中了解到它不会编译,因为fabs(-9)
需要一个双精度,并且编译器无法将 -9 转换为 -9.0,但在第二个代码中,编译器会将 i=-9
转换为 @987654331 @ 在编译时,所以 fabs(i)
可以正常工作。
还有更好的解释吗?
另一件事,为什么编译器不能接受fabs(-9)
并像我们在c# 中那样自动将int 值转换为double?
[*]:
Error: more than one instance of overloaded function "fabs" matches the argument list:
function "fabs(double _X)"
function "fabs(float _X)"
function "fabs(long double _X)"
argument types are: (int)
【问题讨论】:
这里没有编译器错误:coliru.stacked-crooked.com/a/80c5484bda892461 【参考方案1】:在 C++ 中,std::abs
对有符号整数和浮点类型都进行了重载。 std::fabs
仅处理浮点类型(C++11 之前)。请注意,std::
很重要;由于遗留原因而通常可用的 C 函数 ::abs
将仅处理 int
!
问题
float f2= fabs(-9);
不是没有从int
(-9
的类型)到double
的转换,而是编译器不知道选择哪个转换(int
-> float
, @987654335 @, long double
) 因为这三个中的每一个都有一个std::fabs
。您的解决方法明确告诉编译器使用 int
-> double
转换,因此歧义消失了。
C++11 通过添加double fabs( Integral arg );
解决了这个问题,这将返回转换为double
的任何整数类型的abs
。显然,这个重载也可以在 C++98 模式下使用 libstdc++ 和 libc++。
一般来说,只要使用std::abs
,它就会做正确的事。 (@Shafik Yaghmour 指出的Interesting pitfall。无符号整数类型在 C++ 中会做一些有趣的事情。)
【讨论】:
一般来说,只要使用std::abs,它就会做正确的事。 ...见Is std::abs(0u) ill-formed? @ShafikYaghmour 有趣,我从来没有遇到过。令人惊讶的是,无符号整数在 C++ 中造成的破坏如此之大。将无符号整数转换为double
的“正确”实现并不是我期望的代码执行 TBH。
别误会,这是一个很好的答案,我偶然遇到了这个问题,特别是因为存在实现差异并且它仍然处于打开状态,所以需要注意这一点。
@ShafikYaghmour 同意,我在答案中添加了备注,谢谢。【参考方案2】:
对于 C++ 11,单独使用 abs()
是非常危险的:
#include <iostream>
#include <cmath>
int main()
std::cout << abs(-2.5) << std::endl;
return 0;
这个程序输出2
作为结果。 (See it live)
始终使用std::abs()
:
#include <iostream>
#include <cmath>
int main()
std::cout << std::abs(-2.5) << std::endl;
return 0;
这个程序输出2.5
。
您可以使用using namespace std;
避免意外结果,但我建议您反对它,因为这通常被认为是不好的做法,而且您必须搜索using
指令才能知道abs()
是否意味着@ 987654331@ 过载或double
过载。
【讨论】:
我发现了同样的问题。对我来说 abs() 和 std::abs() 都会丢失小数部分。 fabs() 虽然有效。知道为什么吗? @jmoraal 抱歉,不,我不知道可能导致此问题的原因... 可能是旧编译器?您可以将此作为问题发布并包括所有详细信息,例如代码和使用的编译器。【参考方案3】:我的 Visual C++ 2008 不知道从 long double fabs(long double)
、float fabs(float)
或 double fabs(double)
中选择哪个。
在语句double i = -9;
中,编译器会知道-9
应该转换为double
,因为i
的类型是double
。
abs()
在stdlib.h
中声明,它将处理int
值。
fabs()
在math.h
中声明,它将处理double
值。
【讨论】:
在 C++ 中abs
和 fabs
都在 <cmath>
: en.cppreference.com/w/cpp/numeric/math/fabs
@NathanOliver std::abs
和 std::fabs
是。其他的可以,但不一定。以上是关于abs和fabs有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
numba 中的@jit 和@vectorize 有啥区别?