简体   繁体   English

abs 和 fabs 有什么区别?

[英]What's the difference between abs and fabs?

I checked the difference between abs and fabs on python here我在这里检查了 python 上absfabs之间的区别

As I understand there are some difference regarding the speed and the passed types, but my question related to native c++ on VS据我了解,速度和传递的类型存在一些差异,但我的问题与 VS 上的本机 C++ 相关

Regarding the VS I tried the following on Visual Studio 2013 (v120) :关于 VS,我在Visual Studio 2013 (v120)上尝试了以下操作:

float f1= abs(-9.2); // f = 9.2
float f2= fabs(-9); // Compile error [*]

So fabs(-9) it will give me a compiler error, but when I tried to do the following:所以fabs(-9)它会给我一个编译器错误,但是当我尝试执行以下操作时:

double i = -9;
float f2= fabs(i); // This will work fine

What I understand from the first code that it will not compile because fabs(-9) need a double, and the compiler could not convert -9 to -9.0, but in the second code the compiler will convert i=-9 to i=-9.0 at compile time so fabs(i) will work fine.我从第一个代码中了解到它不会编译,因为fabs(-9)需要一个 double,并且编译器无法将 -9 转换为 -9.0,但是在第二个代码中,编译器会将i=-9转换为i=-9.0编译时为i=-9.0 ,因此fabs(i)可以正常工作。

Any better explanation?有更好的解释吗?

Another thing, why the compiler can't accept fabs(-9) and convert the int value to double automatically like what we have in c#?另一件事,为什么编译器不能接受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)   

In C++, std::abs is overloaded for both signed integer and floating point types.在 C++ 中, std::abs对于有符号整数和浮点类型都被重载。 std::fabs only deals with floating point types (pre C++11). std::fabs仅处理浮点类型(C++11 之前)。 Note that the std:: is important;请注意std::很重要; the C function ::abs that is commonly available for legacy reasons will only handle int !由于遗留原因通常可用的 C 函数::abs只能处理int

The problem with问题在于

float f2= fabs(-9);

is not that there is no conversion from int (the type of -9 ) to double , but that the compiler does not know which conversion to pick ( int -> float , double , long double ) since there is a std::fabs for each of those three.并不是说没有从int-9的类型)到double ,而是编译器不知道要选择哪个转换( int -> float , double , long double ),因为有一个std::fabs这三个中的每一个。 Your workaround explicitly tells the compiler to use the int -> double conversion, so the ambiguity goes away.您的解决方法明确告诉编译器使用int -> double转换,因此歧义消失了。

C++11 solves this by adding double fabs( Integral arg ); C++11 通过添加double fabs( Integral arg );解决了这个问题double fabs( Integral arg ); which will return the abs of any integer type converted to double .这将返回转换为double的任何整数类型的abs Apparently, this overload is also available in C++98 mode with libstdc++ and libc++.显然,这个重载也可以在 C++98 模式下使用 libstdc++ 和 libc++。

In general, just use std::abs , it will do the right thing.一般来说,只需使用std::abs ,它就会做正确的事情。 ( Interesting pitfall pointed out by @Shafik Yaghmour . Unsigned integer types do funny things in C++.) @Shafik Yaghmour指出了一个有趣的陷阱。无符号整数类型在 C++ 中做了一些有趣的事情。)

With C++ 11, using abs() alone is very dangerous:对于 C++ 11,单独使用abs()是非常危险的:

#include <iostream>
#include <cmath>

int main() {
    std::cout << abs(-2.5) << std::endl;
    return 0;
}

This program outputs 2 as a result.该程序的结果是输出2 ( See it live ) 现场观看

Always use std::abs() :始终使用std::abs()

#include <iostream>
#include <cmath>

int main() {
    std::cout << std::abs(-2.5) << std::endl;
    return 0;
}

This program outputs 2.5 .该程序输出2.5

You can avoid the unexpected result with using namespace std; using namespace std;可以避免意外结果using namespace std; but I would adwise against it, because it is considered bad practice in general, and because you have to search for the using directive to know if abs() means the int overload or the double overload.但我会反对它,因为它通常被认为是不好的做法,并且因为您必须搜索using指令才能知道abs()是指int重载还是double重载。

My Visual C++ 2008 didn't know which to choice from long double fabs(long double) , float fabs(float) , or double fabs(double) .我的 Visual C++ 2008 不知道从long double fabs(long double)float fabs(float)double fabs(double)选择哪个。

In the statement double i = -9;在语句double i = -9; , the compiler will know that -9 should be converted to double because the type of i is double . ,编译器会知道-9应该转换为double因为i的类型是double


abs() is declared in stdlib.h and it will deal with int value. abs()stdlib.h声明,它将处理int值。

fabs() is declared in math.h and it will deal with double value. fabs()math.h声明,它将处理double值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM