C / C ++ में लंबे समय तक


84

मैं GNU के C ++ कंपाइलर पर इस कोड की कोशिश कर रहा हूं और इसके व्यवहार को समझने में असमर्थ हूं:

#include <stdio.h>;

int main()
{
    int  num1 = 1000000000;
    long num2 = 1000000000;
    long long num3;
    //num3 = 100000000000;
    long long num4 = ~0;

    printf("%u %u %u", sizeof(num1), sizeof(num2), sizeof(num3));
    printf("%d %ld %lld %llu", num1, num2, num3, num4);
    return 0;
}

जब मैं टिप्पणी लाइन को अनसुना कर देता हूं, तो कोड संकलित नहीं होता है और एक त्रुटि दे रहा है:

त्रुटि: पूर्णांक स्थिरांक लंबे प्रकार के लिए बहुत बड़ा है

लेकिन, अगर कोड को संकलित किया जाता है और इसे निष्पादित किया जाता है, तो यह 10000000000 से अधिक मूल्य का उत्पादन करता है।

क्यों?


8
अब बहुत देर हो सकती है लेकिन भविष्य के पाठकों के लिए, मेरा सुझाव है कि आप उपयोग <stdint.h>और उपयोग करें uint64_t। 64 बिट मान प्रदर्शित करने के लिए,printf( "%" PRIu64 "\n", val);
उत्साही

@enthusiasticgeek <stdint.h>शामिल,uint64_t a = 0xffffffffffffff; printf( "%" PRIu64 "\n",a ); : error: expected ‘)’ before ‘PRIu64’ printf( "%" PRIu64 "\n",a ); :: warning: spurious trailing ‘%’ in format [-Wformat=] printf( "%" PRIu64 "\n",a );
चरवाहा

जवाबों:


147

अक्षर 100000000000 एक शाब्दिक पूर्णांक स्थिरांक बनाते हैं, लेकिन मूल्य प्रकार के लिए बहुत बड़ा है int। आपको शाब्दिक के प्रकार को बदलने के लिए एक प्रत्यय का उपयोग करने की आवश्यकता है, अर्थात

long long num3 = 100000000000LL;

प्रत्यय LLप्रकार में शाब्दिक बनाता है long long। सी "स्मार्ट" नहीं है जो इसे बाईं ओर के प्रकार से समाप्त करने के लिए पर्याप्त है, प्रकार स्वयं शाब्दिक की एक संपत्ति है, न कि उस संदर्भ में जिसमें इसका उपयोग किया जा रहा है।


47
वापस जब इस जवाब लिखा गया था यह शायद सही था, लेकिन अब सी ++ मानक का कहना है कि कोई प्रत्यय के साथ एक पूर्णांक शाब्दिक के प्रकार का पहला है int, long intऔर long long intजिसमें अपने मूल्य का प्रतिनिधित्व किया जा सकता है। [C ++ now2.14.2 / 2] इसलिए अब पूर्णांक शाब्दिक पर 'LL' प्रत्यय जोड़ने की आवश्यकता नहीं है जो अन्य प्रकारों के लिए बहुत बड़ा है।
bames53

8
इसका कारण यह समस्या थी, क्योंकि सी + + 'स्मार्ट' नहीं था, यह निर्धारित करने के लिए कि वेरिएबल के प्रकार से शाब्दिक प्रकार निर्धारित करने के लिए पर्याप्त नहीं है, यह केवल इसलिए होगा क्योंकि कंपाइलर एक्सटेंशन विस्तारित पूर्णांक को लागू नहीं करता था टाइप करें कि यह मानक भाषा के साथ अच्छी तरह से काम करेगा। C ++ में अब ऐसे नियम हैं जो किसी भी विस्तारित पूर्णांक प्रकार को मानक के साथ बेहतर रूप से एकीकृत करेंगे: open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf
bames53

4
@ मुझे लगता है कि इन सुझावों के अनुसार उत्तर को संपादित किया जाना चाहिए।
एंटोनियो

26

प्रयत्न:

num3 = 100000000000LL;

और BTW, C ++ में यह एक कंपाइलर एक्सटेंशन है, मानक लंबे समय तक परिभाषित नहीं करता है, C99 का हिस्सा है।


11
खैर, C ++ 11 अब लंबे समय तक परिभाषित करता है
मोहम्मद अल-नकीब

4

यह निर्भर करता है कि आप किस मोड में संकलन कर रहे हैं। लंबे समय तक C ++ मानक का हिस्सा नहीं है, लेकिन केवल (आमतौर पर) विस्तार के रूप में समर्थित है। यह शाब्दिक प्रकार को प्रभावित करता है। दशमलव पूर्णांक शाब्दिक बिना किसी प्रत्यय के हमेशा प्रकार के होते हैं यदि इंट पर्याप्त संख्या का प्रतिनिधित्व करने के लिए पर्याप्त है, अन्यथा लंबे समय तक। यदि संख्या लंबे समय के लिए बहुत बड़ी है, तो परिणाम कार्यान्वयन-परिभाषित है (शायद पिछड़े संगतता के लिए छंटनी किए गए टाइप लंबे इंट की संख्या)। इस मामले में आपको लंबे समय तक विस्तार (अधिकांश संकलक पर) को सक्षम करने के लिए एलएल प्रत्यय का स्पष्ट रूप से उपयोग करना होगा।

अगले सी ++ संस्करण आधिकारिक तौर पर लंबे समय तक एक तरह से समर्थन करेगा कि आपको किसी भी प्रत्यय की आवश्यकता नहीं होगी जब तक कि आप स्पष्ट रूप से बल नहीं चाहते हैं कि शाब्दिक का प्रकार कम से कम लंबे समय तक होना चाहिए। यदि संख्या को लंबे समय तक नहीं दिखाया जा सकता है तो संकलक स्वचालित रूप से एलएल प्रत्यय के बिना भी लंबे समय तक उपयोग करने का प्रयास करेगा। मेरा मानना ​​है कि यह C99 का व्यवहार भी है।


1

आपका कोड यहाँ ठीक संकलित करता है (यहां तक ​​कि उस लाइन के साथ भी) इसे बदलना पड़ा

num3 = 100000000000000000000;

चेतावनी प्राप्त करना शुरू करें।


क्या संकलक? C ++ में, एक पूर्णांक शाब्दिक int या long का छोटा होता है जो इसमें फिट बैठता है। C99 में, यह int, long, long long का सबसे छोटा है। इसलिए जब सी-++ पर लंबे समय तक एक गैर-मानक एक्सटेंशन के रूप में लंबे समय तक बोल्ट किया जाता है, तो शायद आपके कंपाइलर ने भी C99 नियमों को शाब्दिक रूप से अपनाया है।
स्टीव जेसप

64 बिट लाइनक्स सिस्टम पर gcc संस्करण 4.3.2 (डेबियन 4.3.2-1.1)।
ओमरी यदन

@SteveJessop थोड़ा देर से शायद: लेकिन लंबे समय तक जरूरी नहीं है 64 बिट्स। ज्यादातर समय यह होता है, लेकिन आपकी कोई गारंटी नहीं है कि यह हर जगह होगा। आपके पास एकमात्र गारंटी यह है कि यह इंट के रूप में कम से कम उतना बड़ा है, जो बदले में कम से कम उतना ही बड़ा है जितना एक छोटा इंट, जो बदले में कम से कम उतना ही बड़ा है जितना कि एक चार। अंत में, चार को बड़े अक्षर के रूप में परिभाषित किया गया है ताकि कार्यान्वयन के मूल वर्ण (आमतौर पर 8-बिट) में हर चरित्र का प्रतिनिधित्व किया जा सके
पौलस pa६

@ pauluss86: मैं गारंटी के बारे में बात नहीं कर रहा था। ओमी ने कहा कि वह 64 बिट डेबियन सिस्टम पर gcc 4.3.2 का उपयोग कर रहा था। मैंने देखा कि इसने बताया कि वह क्या देख रहा था (मुझे सामान्य ज्ञान की बात के रूप में पता चला) इस तरह के सिस्टम पर डिफ़ॉल्ट रूप longसे उस OS के LP64 ABI के साथ 64 बिट का उपयोग करने के लिए gcc को कॉन्फ़िगर किया गया है ।
स्टीव जेसप

@SteveJessop मैं सुझाव नहीं दे रहा हूँ कि आपकी टिप्पणी गलत है! केवल इस ओर इशारा करते हुए कि यह धारणा कि एक लंबी हमेशा 64 बिट्स हर जगह होती है, जो दुर्भाग्य से बहुत सारे लोग सोचते हैं, खतरनाक है।
pauluss86
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.