Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> C++

C++ में बिल्ट-इन डेटा टाइप्स की वैध रेंज पार करने पर क्या होता है?


C++ में जब बिल्ट-इन डेटा टाइप्स की वैध रेंज से बाहर मान असाइन किया जाता है, तो व्यवहार टाइप पर निर्भर करता है: अनसाइन्ड टाइप्स रैप-अराउंड करते हैं (well-defined), जबकि साइन्ड टाइप्स अनडिफाइंड बिहेवियर (UB) दिखाते हैं।

1. अनसाइन्ड टाइप्स: Well-Defined Wraparound

अनसाइन्ड इंटीजर्स मॉडुलो 2^N अंकगणित का पालन करते हैं (C++ स्टैंडर्ड द्वारा गारंटीड)।

#include <iostream>
#include <climits>
using namespace std;

int main() {
    unsigned char uc = 255;  // MAX: 255
    cout << "uc = " << (int)uc << endl;
    uc++;  // 256 → 0 (wraparound)
    cout << "uc++ = " << (int)uc << endl;
    
    unsigned int ui = UINT_MAX;
    cout << "UINT_MAX = " << ui << endl;
    ui++;  // 0 हो जाता है
    cout << "UINT_MAX + 1 = " << ui << endl;
    
    // लूप में समस्या
    cout << "\nUnsigned loop issue:\n";
    for (unsigned int i = 10; i >= 0; --i) {
        cout << i << " ";
        if (i == 0) break;  // अनंत लूप से बचने के लिए!
    }
    cout << endl;
    
    return 0;
}

आउटपुट

uc = 255
uc++ = 0
UINT_MAX = 4294967295
UINT_MAX + 1 = 0

Unsigned loop issue:
10 9 8 7 6 5 4 3 2 1 0

2. साइन्ड टाइप्स: Undefined Behavior (UB)

साइन्ड इंटीजर ओवरफ्लो अनडिफाइंड बिहेवियर है। कंपाइलर कुछ भी कर सकता है: रैपअराउंड, क्रैश, ऑप्टिमाइज़ अवे, आदि।

#include <iostream>
#include <climits>
using namespace std;

int main() {
    int x = INT_MAX;  // 2147483647
    cout << "INT_MAX = " << x << endl;
    
    // UB! कुछ भी हो सकता है
    x = x + 1;  
    cout << "INT_MAX + 1 = " << x << " (UB - result unpredictable)\n";
    
    // कंपाइलर इस चेक को ऑप्टिमाइज़ अवे कर सकता है!
    if (x + 1 > x) {
        cout << "x+1 > x is true\n";
    } else {
        cout << "x+1 > x is FALSE (due to UB optimization!)\n";
    }
    
    return 0;
}

आउटपुट (कंपाइलर-निर्भर)

INT_MAX = 2147483647
INT_MAX + 1 = -2147483648 (wraparound on this compiler)
x+1 > x is FALSE (due to UB optimization!)

3. कैरेक्टर और बूल टाइप्स

#include <iostream>
using namespace std;

int main() {
    // signed char: -128 से 127
    signed char sc = 127;
    cout << "sc = " << (int)sc;
    sc++;  // UB for signed!
    cout << ", sc++ = " << (int)sc << endl;
    
    // unsigned char: 0 से 255
    unsigned char uc = 255;
    uc++;  // Well-defined: 0
    cout << "uc++ = " << (int)uc << endl;
    
    // bool: केवल 0 या 1 स्टोर कर सकता है
    bool b = true;
    b = b + true;  // true (1) में प्रोमोट होता है, 1+1=2 → true (1)
    cout << "bool true+true = " << b << endl;
    
    // लूप इश्यू
    cout << "\nBool loop:\n";
    for (bool b = true; b <= 6; b++) {
        cout << b << " ";  // अनंत लूप: b हमेशा true रहता है!
        if (b == false) break; // कभी नहीं पहुंचेगा
    }
    cout << endl;
    
    return 0;
}

आउटपुट

sc = 127, sc++ = -128 (implementation-defined for signed overflow)
uc++ = 0
bool true+true = 1
Bool loop:
1 1 1 1 1 ... (infinite loop)

4. फ्लोटिंग पॉइंट: इन्फिनिटी और NaN

#include <iostream>
#include <cmath>
#include <limits>
using namespace std;

int main() {
    double d = 1e308;
    cout << "d = " << d << endl;
    d *= 10;  // Overflow → infinity
    cout << "d*10 = " << d << endl;
    
    double inf = numeric_limits<double>::infinity();
    double nan = numeric_limits<double>::quiet_NaN();
    
    cout << "inf + 1 = " << inf + 1 << endl;
    cout << "inf - inf = " << inf - inf << " (NaN)\n";
    cout << "0.0 / 0.0 = " << 0.0/0.0 << " (NaN)\n";
    cout << "sqrt(-1) = " << sqrt(-1) << " (NaN)\n";
    
    return 0;
}

बचाव के उपाय

  1. चेक्ड अंकगणित: <climits> के साथ मैनुअल चेक या std::numeric_limits
  2. सेफ लाइब्रेरी: Boost.SafeNumerics, std::add_overflow (C++23 प्रस्तावित)
  3. वाइडर टाइप: कैलकुलेशन के लिए int64_t या long double उपयोग करें
  4. कंपाइलर फ्लैग्स: -ftrapv (GCC/Clang) साइन्ड ओवरफ्लो पर क्रैश करता है
  5. अनसाइन्ड उपयोग करें जब निगेटिव मानों की आवश्यकता न हो (well-defined wraparound)
// सेफ एडिशन फंक्शन
bool safeAdd(int a, int b, int &result) {
    if (b > 0 && a > INT_MAX - b) return false;  // Overflow
    if (b < 0 && a < INT_MIN - b) return false;  // Underflow
    result = a + b;
    return true;
}
  1. - C# में नल करने योग्य डेटा टाइप्स (Nullable Data Types) क्या हैं?

    C# नल करने योग्य प्रकार (nullable types) प्रदान करता है, जिन्हें आप सामान्य मानों की सीमा के साथ-साथ null मान भी असाइन कर सकते हैं।उदाहरण के लिए, आप -2,147,483,648 से 2,147,483,647 तक कोई भी मान या null एक Nullable<int> वेरिएबल में स्टोर कर सकते हैं। इसी तरह, आप true, false, या null एक Nullabl

  1. - C# में पॉइंटर डेटा टाइप्स क्या हैं?

    एक पॉइंटर एक वेरिएबल होता है जिसका मान किसी अन्य वेरिएबल का पता होता है, यानी मेमोरी लोकेशन का सीधा पता। किसी भी वेरिएबल या कॉन्स्टेंट की तरह, आपको इसका उपयोग किसी वेरिएबल के पते को स्टोर करने के लिए करने से पहले पॉइंटर घोषित करना होगा।पॉइंटर का सिंटैक्स:type *var-name;पॉइंटर टाइप घोषित करने का तरीक

  1. - पायथन 3 में स्टैंडर्ड डेटा टाइप्स क्या हैं?

    पायथन के स्टैंडर्ड डेटा टाइप्स में न्यूमेरिक डेटा टाइप्स, सीक्वेंस टाइप्स और डिक्शनरी शामिल हैं जो की-वैल्यू पेयर्स का कलेक्शन है। न्यूमेरिक डेटा टाइप्स के ऑब्जेक्ट्स या तो इंटीजर्स, फ्लोट्स या कॉम्प्लेक्स नंबर्स होते हैं। इंटीजर्स पूर्ण संख्याएं होती हैं, जबकि फ्लोट्स में फ्रैक्शनल पार्ट होता है।