2012-04-01 16 views
13

क्यों d इस उदाहरण में b के बराबर नहीं है?अजीब गणना परिणाम

unsigned int z = 176400; 
    long a = -4; 
    long b = a*z/1000; //b=4294261 
    long c = a*z; // c=-705600 
    long d = c/1000; // d =-705 

मैं विजुअल स्टूडियो 2008, विंडोज एक्सपी, कोर 2duo का उपयोग करता हूं। धन्यवाद।

+6

... क्योंकि डी == सी/1000। क्या यह वास्तविक जीवन है? – outis

+2

@ क्रशानेटर वास्तव में, डी भी बराबर नहीं है। क्या तुमने देखा? –

+3

इस उदाहरण में 1 बराबर 2 क्यों नहीं है: 'int a = 1; int बी = 2; '? –

उत्तर

5

ऐसा लगता है कि आप एक मंच का उपयोग कर रहे हैं जहां int और long समान आकार हैं। (मैं तथ्य यह है कि अगर long सभी मान्य मान unsigned int की आप व्यवहार है कि आप देख रहे हैं नहीं देख पा रहे हैं पकड़ करने में सक्षम था द्वारा इस लगाए गए अनुमान से।)

इसका मतलब है कि अभिव्यक्ति a*z, दोनों a और z में unsigned long में परिवर्तित कर दिए गए हैं और परिणाम unsigned long टाइप किया गया है। (आईएसओ/आईईसी 14882: 2011, 5 [एक्सप्र]/9 ... "अन्यथा, दोनों ऑपरेटरों को हस्ताक्षरित पूर्णांक प्रकार के साथ ऑपरेंड के प्रकार से संबंधित हस्ताक्षरित पूर्णांक प्रकार में परिवर्तित किया जाएगा।"

c है unsigned long से long तक इस अभिव्यक्ति को परिवर्तित करने का नतीजा और आपके मामले में यह परिणामस्वरूप कार्यान्वयन परिभाषित परिणाम (जो ऋणात्मक होता है) के रूप में a*z के सकारात्मक मान पर हस्ताक्षर किए गए long में प्रतिनिधित्व योग्य नहीं है। c/1000 में, 1000 को long और long डिवीजन में परिवर्तित किया गया है (कोई इरादा नहीं है) जिसके परिणामस्वरूप long (जो ऋणात्मक होता है) और d पर संग्रहीत किया जाता है।

भाव a*z/1000, 1000 (प्रकार int की अभिव्यक्ति) में unsigned long में बदल जाती है और विभाजन एक सकारात्मक परिणाम में जिसके परिणामस्वरूप दो unsigned long के बीच किया जाता है। यह परिणाम long के रूप में प्रतिनिधित्व योग्य है और मान long में कनवर्ट करने और b पर संग्रहीत करने पर अपरिवर्तित है।

+0

यह वास्तव में एमएस सी कंपाइलर पर मामला है। – Inisheer

+0

साइन ओवर ओवरफ्लो अपरिभाषित व्यवहार है, लेकिन जिस तरह से। –

+1

@KerrekSB: हाँ, लेकिन इस उदाहरण में कोई हस्ताक्षरित ओवरफ़्लो नहीं है। –

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