abs和fabs有啥区别?

Posted

技术标签:

【中文标题】abs和fabs有啥区别?【英文标题】:What's the difference between abs and fabs?abs和fabs有什么区别? 【发布时间】:2015-11-16 15:07:48 【问题描述】:

我在 python here 上检查了 absfabs 之间的区别

据我了解,速度和传递的类型存在一些差异,但我的问题与 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++ 中 absfabs 都在 &lt;cmath&gt;: en.cppreference.com/w/cpp/numeric/math/fabs @NathanOliver std::absstd::fabs 是。其他的可以,但不一定。

以上是关于abs和fabs有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Python中abs()和math.fabs()区别

C语言,fabs有多个重载函数,请问是哪里错了,急在线等

numba 中的@jit 和@vectorize 有啥区别?

python视角中的参数和参数有啥区别[不重复:)]? [复制]

文件的格式都有啥??啥区别???

ab类功放有啥特点?