C++ abs 和 fabs 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33738509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:18:55  来源:igfitidea点击:

What's the difference between abs and fabs?

c++visual-studio-2013cmath

提问by Hazem Abdullah

I checked the difference between absand fabson python here

我在这里检查了pythonabsfabspython之间的区别

As I understand there are some difference regarding the speed and the passed types, but my question related to native c++ on V.S.

据我了解,速度和传递的类型存在一些差异,但我的问题与 VS 上的本机 C++ 相关

Regarding the V.S. 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=-9to i=-9.0at compile time so fabs(i)will work fine.

我从第一个代码中了解到它不会编译,因为fabs(-9)需要一个 double,并且编译器无法将 -9 转换为 -9.0,但在第二个代码中,编译器将在编译时转换i=-9i=-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)   

采纳答案by Baum mit Augen

In C++, std::absis overloaded for both signed integer and floating point types. std::fabsonly deals with floating point types (pre C++11). Note that the std::is important, the C function ::absthat is commonly available for legacy reasons will only handle int!

在 C++ 中,std::abs对于有符号整数和浮点类型都重载。std::fabs只处理浮点类型(C++11 之前)。请注意,std::重要的是,由于::abs遗留原因而普遍可用的 C 函数只会处理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::fabsfor each of those three. Your workaround explicitly tells the compiler to use the int-> doubleconversion, so the ambiguity goes away.

并不是没有从int(的类型-9)到 的转换double,而是编译器不知道选择哪个转换(int-> float, double, long double),因为std::fabs这三个中的每一个都有一个。您的解决方法明确告诉编译器使用int->double转换,因此歧义消失了。

C++11 solves this by adding double fabs( Integral arg );which will return the absof any integer type converted to double. Apparently, this overload is also available in C++98 mode with libstdc++ and libc++.

C++11 通过添加double fabs( Integral arg );which 将返回abs转换为double. 显然,这个重载也可以在 C++98 模式下使用 libstdc++ 和 libc++。

In general, just use std::abs, it will do the right thing. (Interesting pitfallpointed out by @Shafik Yaghmour. Unsigned integer types do funny things in C++.)

一般来说,只要使用std::abs,它就会做正确的事情。(@Shafik Yaghmour指出了一个有趣的陷阱。无符号整数类型在 C++ 中做了一些有趣的事情。)

回答by alain

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 2as a result. (See it live)

该程序2作为结果输出。(现场观看

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;but I would adwise against it, because it is considered bad practice in general, and because you have to search for the usingdirective to know if abs()means the intoverload or the doubleoverload.

你可以避免意外的结果,using namespace std;但我会反对它,因为它通常被认为是不好的做法,并且因为你必须搜索using指令才能知道是否abs()意味着int超载或double超载。

回答by MikeCAT

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;, the compiler will know that -9should be converted to doublebecause the type of iis double.

在语句中double i = -9;,编译器会知道-9应该转换为,double因为类型idouble



abs()is declared in stdlib.hand it will deal with intvalue.

abs()在中声明,stdlib.h它将处理int值。

fabs()is declared in math.hand it will deal with doublevalue.

fabs()在中声明,math.h它将处理double值。