![](/img/trans.png)
[英]Is there any difference between std::abs and std::fabs when applied to floating point values?
[英]What's the difference between abs and fabs?
我在這里檢查了 python 上abs
和fabs
之間的區別
據我了解,速度和傳遞的類型存在一些差異,但我的問題與 VS 上的本機 C++ 相關
關於 VS,我在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)
需要一個 double,並且編譯器無法將 -9 轉換為 -9.0,但是在第二個代碼中,編譯器會將i=-9
轉換為i=-9.0
編譯時為i=-9.0
,因此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)
在 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 );
解決了這個問題double fabs( Integral arg );
這將返回轉換為double
的任何整數類型的abs
。 顯然,這個重載也可以在 C++98 模式下使用 libstdc++ 和 libc++。
一般來說,只需使用std::abs
,它就會做正確的事情。 ( @Shafik Yaghmour指出了一個有趣的陷阱。無符號整數類型在 C++ 中做了一些有趣的事情。)
對於 C++ 11,單獨使用abs()
是非常危險的:
#include <iostream>
#include <cmath>
int main() {
std::cout << abs(-2.5) << std::endl;
return 0;
}
該程序的結果是輸出2
。 (現場觀看)
始終使用std::abs()
:
#include <iostream>
#include <cmath>
int main() {
std::cout << std::abs(-2.5) << std::endl;
return 0;
}
該程序輸出2.5
。
using namespace std;
可以避免意外結果using namespace std;
但我會反對它,因為它通常被認為是不好的做法,並且因為您必須搜索using
指令才能知道abs()
是指int
重載還是double
重載。
我的 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
值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.