2013-02-26 12 views
11

वास्तव में मैं सी ++ में रेंज अभिव्यक्ति पर काम कर रहा हूं। तो क्या मैं चाहता हूँ कि अगर मैं की तरहएक डबल मान मुद्रित करने के लिए जो कि एक और डबल मान से कम है?

x<1 

तो किसी भी अभिव्यक्ति है मेरी

double getMax(...); 

एक नंबर लाइन पर एक डबल मूल्य बस से पहले 1.000 (डबल परिशुद्धता) है कि वापस आ जाएगी।

मैं इस

double getMax(double& a) 
{ 
    return (a-numeric_limits<double>::min()); 
} 

कर की कोशिश की लेकिन मैं अभी भी वापसी कथन में एक के रूप में एक ही मूल्य मिल रहा है।

मुझे लगता है कि सी ++ इसे कोउट स्टेटमेंट में निकटतम डबल में परिवर्तित कर रहा है।

int main() 
{ 
    double a = 32; 
    cout<<scientific<<getMax(a)<<endl; 
    return 0; 
} 

उत्पादन:

3.200000e+001 
+0

नीचे दिए गए सभी ने कहा, 'getMax' खुले अंतराल के लिए समझ में नहीं आता है और ['getSup'] (http://en.wikipedia.org/wiki/Supremum) को 1 बिल्कुल वापस करना चाहिए। –

उत्तर

10

सबसे पहले, आप यह सुनिश्चित करें कि आप वास्तव में पर्याप्त रूप से कई अंक प्रिंट double के सभी प्रदर्शनीय मान प्रदर्शित होते सुनिश्चित करने के लिए की जरूरत है। आप इस इस प्रकार है (इस के लिए सुनिश्चित करें कि आप #include <iomanip> बनाने) कर सकते हैं:

std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << getMax(a) << std::endl; 

दूसरे, numeric_limits<>::min इस के लिए उपयुक्त नहीं है। यदि आपका प्रारंभिक मान 1.0 है, तो आप numeric_limits<double>::epsilon का उपयोग कर सकते हैं, जो 1.0 से सबसे छोटा अंतर है जो प्रतिनिधित्व योग्य है।

हालांकि, आपके कोड उदाहरण में, प्रारंभिक मान 32 है। Epsilon जरूरी नहीं है कि इसके लिए काम करते हैं। इस मामले में सही ईपीएसलॉन की गणना करना मुश्किल है।

#include <iostream> 
#include <limits> 
#include <iomanip> 
#include <cmath> 

double getMax(double a) 
{ 
    return std::nextafter(a,std::numeric_limits<double>::lowest()); 
} 

int main() 
{ 
    double a = 32; 
    std::cout << std::scientific 
       << std::setprecision(std::numeric_limits<double>::max_digits10) 
       << getMax(a) 
       << std::endl; 
    return 0; 
} 

मैं भी यह liveworkspace पर डाल दिया है:

हालांकि, अगर आप सी ++ 11 उपयोग कर सकते हैं (*), वहाँ cmath शीर्षक में एक समारोह के लिए आप क्या std::nextafter की आवश्यकता है वह यह है कि ।

व्याख्या करने के लिए:

double nextafter(double from, double to); 

करने की दिशा में से की अगली प्रदर्शनीय मान देता है। तो मैंने यह सुनिश्चित करने के लिए निर्दिष्ट किया है कि आपको अगले प्रतिनिधित्व योग्य मान तर्क से कम मिलता है।

(*) नीचे टोनी डी की टिप्पणी देखें। आपके पास C++ 11 के बिना nextafter() तक पहुंच हो सकती है।

+1

टिप्पणी लाइन को केवल 'ए - ए * ... :: epsilon() 'नहीं होना चाहिए? –

+0

ओह, ठीक है, यह शून्य की ओर गोल होगा। और '2 * ए * ... :: epsilon()' गोलाकार होने पर सही मूल्य होगा, लेकिन दो बार बड़ा नहीं होगा। ओच आउच –

+0

@JanHudec '10' कोड सबमिट करने से पहले मैंने परीक्षण किए गए एक परीक्षण से बचे हुए थे। मैंने इसे हटा दिया है। चाहे 'ए' के ​​साथ गुणा करना सही है, मुझे नहीं पता। सही कारक चुनना मेरे ज्ञान से परे है - मेरा मुख्य बिंदु सी ++ 11 में 'अगले बाद' का उपयोग करना था। ईपीएसलॉन की सही गणना के लिए, कोई और जवाब तैयार कर सकता है। – jogojapan

0

मैं तुम्हें सही विचार मिल गया है लगता है। प्रश्न के लिए Setting the precision of a double without using stream (ios_base::precision) देखें, लेकिन उदाहरण के लिए वे precision का उपयोग करने के लिए देते हैं। आप 53 की सटीकता के साथ मुद्रण की तरह कुछ कोशिश करना चाहेंगे।

जिस तरह से मैं आमतौर पर "करीब लेकिन काफी नहीं" देखता हूं, इसमें एक अंतर सीमा (आमतौर पर ईपीएसलॉन कहा जाता है) स्थापित करना शामिल है। उस स्थिति में, आप getMax फ़ंक्शन का उपयोग नहीं करेंगे, लेकिन आपके उपयोग में कम से कम एक ईपीएसलॉन उपयोग किया जाएगा। (।। आप एप्सिलॉन मूल्य और ऑपरेटर ओवरलोडिंग के साथ एक वर्ग कर सकता है मैं एक प्लेग की तरह अधिक भार ऑपरेटर से बचने के लिए करते हैं)

मूल रूप से, आप आवश्यकता होगी:

bool lessThanEpsilon(double number, double lessThan, double epsilon) 
{ 
    return (lessThan - number >= epsilon); 
} 

अन्य किस्मों, निश्चित रूप से कर रहे हैं । के बराबर है की जाँच करेगा if Math.abs(number - equals) < epsilon

संबंधित मुद्दे