2015-12-16 8 views
5

द्वारा गुणा करने के समान नहीं है, मैंने केआर अभ्यास 2.1 का प्रयास किया - सीधे गणना द्वारा long चर की सीमा निर्धारित करें। क्योंकि बाएँ पारी अतिप्रवाह मुझे लगता हैजब बाएं शिफ्ट 2

#include <stdio.h> 
#include <limits.h> 

int main() 
{ 
    unsigned short long_bits = sizeof(long) * CHAR_BIT; 
    printf("LONG_MAX = %ld\n", (1L << (long_bits - 1)) - 1); 
    printf("LONG_MIN = %ld\n", (-1) * (1L << (long_bits - 1))); 
    printf("ULONG_MAX (1) = %lu\n", (1UL << long_bits) - 1); // doesn't work 

    printf("ULONG_MAX (2) = %lu\n", 2*(1UL << (long_bits - 1)) - 1); // work 
    printf("\n"); 
} 
  • ULONG_MAX (1) = 0 गलत है।
  • ULONG_MAX (2) = 18446744073709551615 तो ऐसा लगता है कि बाईं पारी ऑपरेटर अतिप्रवाह से ग्रस्त द्वारा 2.

एक गुणा के साथ पिछले बाईं पारी की जगह सही लगता है, लेकिन गुणा नहीं करता है? क्या यह मध्यवर्ती गणना 2*(1UL << (long_bits - 1)) को long से कुछ प्रकार के लिए प्रचारित करती है? मेरी मशीन में, long और long long बिल्कुल वही हैं (8 बाइट्स)।


संपादित करें: लुंडिन के रूप में बताया, सभी ULONG_MAX के लिए आवश्यक printf("ULONG_MAX = %lu\n", ~0L);

इस मामले में बाईं पारी का प्रयोग की वजह से यूबी, और 2 से गुणा संभावित यूबी भी है (हालांकि मामला 2 दिखता का परिणाम सही बात)।

+4

अंगूठे के नियम के रूप में: अंकगणित (संभावित) अतिप्रवाह से हस्ताक्षर किए गए अंकगणित; हस्ताक्षरित अंकगणित * * ओवरफ्लो नहीं कर सकता (क्योंकि मॉड्यूल 2^एन प्रदर्शन किया गया था)। – Jens

+0

केस 2 सही नहीं है ... मामले के लिए ओवरफ्लो के कारण 1 – LPs

+0

@ एलपी - केस 2 का आउटपुट हालांकि सही लगता है। यह मेरा सवाल है, इस मामले में ओवरफ्लो ऐसा नहीं लगता है – artm

उत्तर

4

एक मूल्य को बाएं स्थानांतरित करने का व्यवहार केवल तभी परिभाषित किया जाता है जब आप जिस राशि को छोड़ रहे हैं वह प्रकार के आकार से कम है। इसलिए, 1UL << long_bits अपरिभाषित व्यवहार है और कुछ भी हो सकता है, जिसमें आपकी नाक से बाहर निकलने वाले डेमॉन शामिल हैं।

n जिस प्रकार हम काम कर रहे हैं उसमें बिट्स की संख्या हो। अभ्यास में, प्लेटफ़ॉर्म के आधार पर, इस मामले में दो व्यवहार होते हैं: या तो, n या इससे अधिक बाएं-शिफ्ट 0 (पूरे बिट-पैटर्न को स्थानांतरित कर दिया गया है) उत्पन्न करता है, या बाएं-शिफ्ट को मॉड्यूलो n कम कर दिया जाता है , इसलिए n स्थानों द्वारा बाएं-शिफ्ट 0 स्थानों पर बाएं शिफ्ट की तरह व्यवहार करता है, 1UL << 0 या 1 प्रदान करता है।

+0

धन्यवाद। मैं सहमत हूं कि केस 1 अपरिभाषित है। मामला 2 सही है? '2 * (1UL << (long_bits - 1)) '' लंबा' प्रकार पकड़ने से अधिक दिखाई देता है, इसलिए मुझे आश्चर्य है कि यह यहां क्यों काम करता है – artm

+1

@artm यह मामला भी अनिर्धारित है। आप अभी क्यों नहीं करते हैं (हस्ताक्षर किए गए लंबे) -1 एल'? – fuz

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