abs 和 fabs 有什么区别?
What's the difference between abs and fabs?
我在 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
到 i=-9.0
在编译时所以 fabs(i)
可以正常工作。
有更好的解释吗?
另一件事,为什么编译器不能像我们在 c# 中那样接受 fabs(-9)
并将 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)
我的 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++ 中,std::abs
为有符号整数和浮点类型重载。 std::fabs
仅处理浮点类型(C++11 之前)。请注意 std::
很重要;由于遗留原因通常可用的 C 函数 ::abs
将仅处理 int
!
的问题
float f2= fabs(-9);
不是没有从int
(-9
的类型)到double
的转换,而是编译器不知道选择哪个转换(int
-> float
, double
, long double
) 因为这三个中的每一个都有一个 std::fabs
。您的解决方法明确告诉编译器使用 int
-> double
转换,因此歧义消失了。
C++11 通过添加 double fabs( Integral arg );
来解决这个问题,这会将 return 任何整数类型的 abs
转换为 double
。显然,这个重载在 C++98 模式下也可以使用 libstdc++ 和 libc++。
一般来说,使用std::abs
就可以了。 (Interesting pitfall pointed out by @Shafik Yaghmour。无符号整数类型在 C++ 中做一些有趣的事情。)
对于 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()
表示 int
重载或 double
重载。
我在 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
到 i=-9.0
在编译时所以 fabs(i)
可以正常工作。
有更好的解释吗?
另一件事,为什么编译器不能像我们在 c# 中那样接受 fabs(-9)
并将 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)
我的 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++ 中,std::abs
为有符号整数和浮点类型重载。 std::fabs
仅处理浮点类型(C++11 之前)。请注意 std::
很重要;由于遗留原因通常可用的 C 函数 ::abs
将仅处理 int
!
float f2= fabs(-9);
不是没有从int
(-9
的类型)到double
的转换,而是编译器不知道选择哪个转换(int
-> float
, double
, long double
) 因为这三个中的每一个都有一个 std::fabs
。您的解决方法明确告诉编译器使用 int
-> double
转换,因此歧义消失了。
C++11 通过添加 double fabs( Integral arg );
来解决这个问题,这会将 return 任何整数类型的 abs
转换为 double
。显然,这个重载在 C++98 模式下也可以使用 libstdc++ 和 libc++。
一般来说,使用std::abs
就可以了。 (Interesting pitfall pointed out by @Shafik Yaghmour。无符号整数类型在 C++ 中做一些有趣的事情。)
对于 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()
表示 int
重载或 double
重载。