2015-11-16 6 views
14

मैं अजगर पर abs और fabs के बीच अंतर की जाँच की (C++) में `बनाम fabs`` abs` के बीच का अंतर है hereक्या

मैं समझता हूँ के रूप में गति और पारित कर दिया प्रकार के बारे में कुछ अंतर देखते हैं, लेकिन मेरे वीएस पर देशी सी ++ से संबंधित प्रश्न

वीएस के संबंध में मैं 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=-9i=-9.0 में कनवर्ट करेगा ताकि fabs(i) ठीक काम करेगा।

कोई बेहतर स्पष्टीकरण?

एक और बात, क्यों संकलक fabs(-9) स्वीकार नहीं कर सकता है और int मान को स्वचालित रूप से डबल में बदलने के लिए सी # में क्या है?

[*]: 

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) 
+0

कोई कंपाइलर त्रुटियां यहां नहीं: http://coliru.stacked-crooked.com/a/80c5484bda892461 – NathanOliver

उत्तर

11

सी ++ में, std::abs दोनों हस्ताक्षरित पूर्णांक और फ़्लोटिंग बिंदु प्रकारों के लिए अधिभारित है। std::fabs केवल फ़्लोटिंग पॉइंट प्रकारों (पूर्व सी ++ 11) से संबंधित है। ध्यान दें कि std:: महत्वपूर्ण है, सी फ़ंक्शन ::abs जो आमतौर पर विरासत कारणों के लिए उपलब्ध है केवल int को संभालेगा!

float f2= fabs(-9); 

के साथ समस्या यह double को int से कोई रूपांतरण (के प्रकार) वहाँ है, लेकिन संकलक नहीं जानता है कि जो रूपांतरण लेने के लिए (int कि नहीं है ->float, double , long double) क्योंकि उनमें से प्रत्येक के लिए std::fabs है। आपका कामकाज स्पष्ट रूप से int ->double रूपांतरण का उपयोग करने के लिए संकलक को बताता है, इसलिए अस्पष्टता दूर हो जाती है।

सी ++ 11 double fabs(Integral arg); जोड़कर इसे हल करता है जो double में परिवर्तित किसी भी पूर्णांक प्रकार के abs को वापस कर देगा। जाहिर है, यह ओवरलोड सी ++ 98 मोड में libstdC++ और libC++ के साथ भी उपलब्ध है।

सामान्य रूप से, बस std::abs का उपयोग करें, यह सही काम करेगा। (।। Interesting pitfall@Shafik Yaghmour द्वारा बताया अहस्ताक्षरित पूर्णांक प्रकार सी में अजीब बातें करते हैं ++)

+1

* सामान्य रूप से, केवल std :: abs का उपयोग करें, यह सही काम करेगा। * ... देखें [std :: abs (0u) खराब गठित है?] (Http://stackoverflow.com/q/29750946/1708801) –

+0

@ShafikYaghmour दिलचस्प, मैं उसमें कभी भाग नहीं पाया। यह आश्चर्यजनक है कि C++ में कितना विनाश एकीकृत पूर्णांक कारण है। "सही" कार्यान्वयन जो हस्ताक्षरित पूर्णांक को 'डबल' में परिवर्तित करता है वह वह नहीं है जो मैं उस कोड को टीबीएच करने की अपेक्षा करता हूं। –

+0

मेरा गलत मत बनो यह एक अच्छा जवाब है, मैं इस गलती से भाग गया और विशेष रूप से कार्यान्वयन भिन्नता के बाद से जागरूक होना अच्छा है और यह अभी भी खुला है। –

2

मेरे दृश्य C++ 2008 नहीं पता था कि जो long double fabs(long double), float fabs(float), या double fabs(double) से चुनाव के लिए।

बयान double i = -9; में, संकलक पता चल जाएगा कि double करने के लिए परिवर्तित किया जाना चाहिए क्योंकि i के प्रकार double है।


abs()stdlib.h में घोषित किया जाता है और यह int मूल्य के साथ सौदा होगा।

fabs()math.h में घोषित किया गया है और यह double मूल्य से निपट जाएगा।

+1

सी ++ 'abs' और' fabs' में 'दोनों में हैं: http://en.cppreference.com/ डब्ल्यू/सीपीपी/न्यूमेरिक/गणित/fabs – NathanOliver

+1

@NathanOliver 'std :: abs' और' std :: fabs' हैं। अन्य हो सकते हैं, लेकिन होना जरूरी नहीं है। – juanchopanza

1

के साथ सी ++ 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; साथ अप्रत्याशित परिणाम से बच सकते हैं, लेकिन मैं इसके विरुद्ध adwise जाएगा क्योंकि यह सामान्य रूप में बुरा व्यवहार माना जाता है, और क्योंकि आप using निर्देश के लिए खोज करने के लिए पता करने के लिए है abs() अर्थ है कि यदि int अधिभार या double अधिभार ।