2009-04-29 12 views
12

numeric_limits लक्षण है कि संख्यात्मक _ सीमा < पूर्णांक (कम से कम एमएस विजुअल स्टूडियो 2008 का उपयोग) विभिन्न प्रकार जानकारी प्राप्त करने का एक सामान्य तरीके से,numeric_limits <T> :: min() की असंगत परिभाषा को कैसे कार्य करें?

template<typename T> 
T min(const std::vector<T>& vect) 
{ 
    T val = std::numeric_limits<T>::min(); 

    for(int i=0 ; i<vect.size() ; i++) 
     val = max(T, vect[i]); 

    return val; 
} 
समस्या

जैसी चीज़ों के लिए सक्षम होने के लिए माना जाता है > :: min() सबसे छोटा नकारात्मक संख्या देता है, जबकि संख्यात्मक _ सीमा < सीमा > :: मिनट() सबसे छोटा सकारात्मक नंबर देता है!

कोई भी इस डिजाइन के पीछे तर्कसंगत जानता है? क्या संख्यात्मक _ सीमाओं का उपयोग करने का कोई बेहतर (अनुशंसित?) तरीका है? ऊपर मेरी विशेष समारोह में निश्चित रूप से प्रारंभ, मैं कर सकता है टी [0] vect है, लेकिन है कि इसका जवाब मैं देख रहा हूँ नहीं है ..

भी देखें (फ्लोटिंग प्वाइंट विशेष) चर्चा here

+0

अपने उदाहरण में दो कीड़े हैं। 1. समारोह, अधिकतम() बुलाया जाना चाहिए, क्योंकि यह अधिक से अधिक तत्व गणना करता है। 2. लाइन "वैल = अधिकतम (टी, vect [i])" होना चाहिए "वैल = अधिकतम (वैल, vect [i])"। – TonJ

उत्तर

1

का संभावित हल

double val = -std::numeric_limits<double>::max(); 
बेशक

होगा, इस numerics_limits के अजीब व्यवहार :: मिनट() जो पूर्णांकों के लिए अलग अलग न्यूनतम/अधिकतम सीमाओं (न्यूनतम देखते हैं कि इस तथ्य के कारण हो सकता है की व्याख्या नहीं करता = -2^एन, अधिकतम = 2^एन -1) लेकिन युगल के लिए नहीं।

+0

std :: numeric_limits :: अधिकतम() == -std :: numeric_limits :: मिनट() है? –

+0

मुझे ऐसा नहीं लगता है - जैसा कि मैंने लिखा था, मुझे लगता है कि लगता है कि न्यूनतम = -2^31, अधिकतम = उदाहरण के लिए 32-बिट डेटाटाइप्स के लिए 2^31-1। यह सबसे बड़ा नकारात्मक/सकारात्मक int मान का प्रतिनिधित्व करता है - जीसीसी यह पुष्टि करता है: "न्यूनतम: -2147483648, अधिकतम: 2147483647" – schnaader

+0

यही वह बिंदु है जिसे मैं बनाने की कोशिश कर रहा हूं। आपका कोड गलत है। –

9

आप बूस्ट पुस्तकालयों का उपयोग कर सकते हैं। लाइब्रेरी न्यूमेरिक रूपांतरण एक श्रेणी प्रदान करता है जिसे बाध्य कहा जाता है जिसे लगातार इस्तेमाल किया जा सकता है।

प्रलेखन here देखें।

4

न्यूनतम() का व्यवहार अजीब नहीं है, यह आपके द्वारा विशेषज्ञ प्रकार के आधार पर FLT_MIN, DBL_MIN या INT_MIN (या उनके संबंधित मान) देता है। तो आपका प्रश्न यह होना चाहिए कि FLT_MIN और DBL_MININT_MIN से भिन्न रूप से परिभाषित किए गए हैं।

दुर्भाग्य से, मुझे उस बाद के प्रश्न का उत्तर नहीं पता है।

मेरा संदेह यह है कि इसे व्यावहारिक उद्देश्यों के लिए परिभाषित किया गया था। पूर्णांक संख्याओं के लिए, आप आमतौर पर अतिप्रवाह/अंडरफ्लो से चिंतित होते हैं, जहां न्यूनतम और अधिकतम मूल्य ब्याज बन जाता है।

फ़्लोटिंग पॉइंट नंबरों के लिए, एक अलग प्रकार का अंडरफ्लो मौजूद है जिसमें गणना के परिणामस्वरूप शून्य से बड़ा मान हो सकता है, लेकिन उस फ़्लोटिंग पॉइंट प्रकार के लिए सबसे छोटे प्रतिनिधित्व योग्य दशमलव से छोटा है। यह जानकर कि सबसे छोटा प्रतिनिधित्व करने वाला फ़्लोटिंग पॉइंट वैल्यू आपको इस मुद्दे के आसपास काम करने की अनुमति देता है। subnormal/denormal संख्याओं पर विकिपीडिया लेख भी देखें।

1

एक खाली वेक्टर लिए सबसे छोटा मान की परिभाषा तर्क दिया जा सकता। यदि वेक्टर खाली है तो कोई छोटा तत्व नहीं है।

बजाय std::min_element उपयोग करने के लिए पसंद करते हैं:

int main() 
{ 
    std::vector<int> v; 
    std::generate_n(std::back_inserter(v), 1000, std::rand); 

    std::vector<int>::iterator it = std::min_element(v.begin(), v.end()); 
    if (it == v.end()) 
    { 
     std::cout << "There is no smallest element" << std::endl; 
    } 
    else 
    { 
     std::cout << "The smallest element is " << *it << std::endl; 
    } 
} 
1

मैं औचित्य के बारे में सुनिश्चित नहीं कर रहा हूँ, लेकिन यह व्यवहार की उम्मीद है। खैर, इस अर्थ में कि जोसुटिस (और, संभवतः मानक) इसका वर्णन करता है!

मिनट(): "miniumum परिमित मूल्य (कम से कम सामान्यीकृत फ्लोटिंग प्वाइंट असमान्यीकरण साथ प्रकार के लिए मूल्य)।"

सबसे अच्छा के रूप में मैं अगर प्रकार नहीं एक पूर्णांक (numeric_limits<>::is_integer) और है बता सकते हैं असमान्यीकरण (numeric_limits<>::has_denorm) min() कि प्रकार के आधार पर छोटी से छोटी प्रदर्शनीय मान प्रदान करेगा है। अन्यथा यह सबसे छोटा मान वापस करेगा - जो नकारात्मक हो सकता है।

अधिक सुसंगत इंटरफ़ेस के लिए Boost numeric/conversion लाइब्रेरी देखें। विशेष रूप से bounds traits class। यहाँ एक टुकड़ा है:

cout << "lowest float:" << boost::numeric::bounds<float>::lowest(); 
cout << "lowest int: " << boost::numeric::bounds<int>::lowest(); 

तुम भी boost::integer library उपयोगी मिल सकता है। यह सी 99 के कुछ पूर्णांक समर्थन (जैसे int_least16_t) सी ++ में लाता है और आपको विशेष आवश्यकता के लिए सर्वोत्तम आकार के प्रकार का चयन करने में मदद कर सकता है। एक उदाहरण:

boost::uint_t<20>::fast fastest20bits; // fastest unsigned integer that 
             // can hold at least 20 bits. 
boost::int_max_value_t<100000>::least // smallest integer that can store 
             // the value 100000. 

मैं अक्सर कि जब मैं बढ़ावा :: सांख्यिक/रूपांतरण में से एक की जरूरत है या बढ़ावा देने :: पूर्णांक मैं उन दोनों की जरूरत है सकते हैं।

1

numeric_limits<int>::minन्यूनतम नकारात्मक संख्या, सभी चल बिन्दु संख्या प्रकार लौट आए, छोटी से छोटी धनात्मक संख्या लौटने जब मैं सूर्य सीसी & जी ++ के साथ यह कोशिश की।

मुझे लगता है कि ऐसा इसलिए है क्योंकि 'सबसे छोटा' और 'न्यूनतम' फ्लोटिंग पॉइंट नंबरों के साथ अलग-अलग चीजों का मतलब है। हालांकि यह थोड़ा अजीब है।

सूर्य सीसी और जी दोनों ++ एक ही परिणाम का उत्पादन:

कम: न्यूनतम: -32,768 अधिकतम: 32767

पूर्णांक: न्यूनतम: -२१४७४८३६४८ अधिकतम: 2147483647

अहस्ताक्षरित int: न्यूनतम : 0 अधिकतम: 4294967295

लंबे: न्यूनतम: -२१४७४८३६४८ अधिकतम: 2147483647

फ्लोट: न्यूनतम: 1.17549e-38 मा एक्स: 3.40282e + 38

डबल: न्यूनतम: 2.22507e-308 अधिकतम: 1.79769e + 308

लंबे डबल: न्यूनतम: 3.3621e-4932 अधिकतम: 1।18973e + 4932

अहस्ताक्षरित लघु: न्यूनतम: 0 अधिकतम: 65535

अहस्ताक्षरित int: न्यूनतम: 0 अधिकतम: 4294967295

अहस्ताक्षरित लंबे: न्यूनतम: 0 अधिकतम: 429496729

template<typename T> 
void showMinMax() 
{ 
    cout << "min: " << numeric_limits<T>::min() << endl; 
    cout << "max: " << numeric_limits<T>::max() << endl; 
    cout << endl; 
} 

int main() 
{ 
cout << "short:"; 
showMinMax<short>() 
...etc...etc.. 
+1

अजीब, numeric_limits :: मिनट यहां एक बहुत ही कम सकारात्मक संख्या देता है (g ++ 3.4। 5)। शायद यह संस्करण/ओएस/कार्यान्वयन पर निर्भर करता है – schnaader

5

यह एक पुरानी धागा है, लेकिन वहाँ एक अद्यतन जवाब है:

सी ++ 11करने के लिए एक lowest() समारोह जोड़ा(See here)

तो अब आप सबसे कम प्रतिनिधित्व करने योग्य नकारात्मक मूल्य प्राप्त करने के लिए std::numeric_limits<double>::lowest() पर कॉल कर सकते हैं।

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