2012-05-10 19 views
7

मैं पाइथन के साथ पिछले कुछ घंटों के लिए शुरुआती के रूप में प्रयोग कर रहा हूं। मैंने एक पुनरावर्ती समारोह लिखा, जो एक्स के रूप में रिकर्स (एक्स) देता है! पायथन और जावा में, दोनों की तुलना करने के लिए। कोड के दो टुकड़े समान हैं, लेकिन किसी कारण से, पायथन एक काम करता है, जबकि जावा कोई नहीं करता है। अजगर में, मैं ने लिखा है:कोड के इन दो समान टुकड़े अलग-अलग परिणाम क्यों उत्पन्न करते हैं?

x = int(raw_input("Enter: ")) 

def recurse(num): 
    if num != 0: 
     num = num * recurse(num-1) 
    else: 
     return 1 

    return num 

print recurse(x) 

कहाँ चर संख्या ही संख्या -1 द्वारा गुणा जब तक यह 0 तक पहुँच जाता है, और परिणाम आउटपुट। जावा में, कोड के समान है, केवल लंबे समय तक:

public class Default { 
    static Scanner input = new Scanner(System.in); 
    public static void main(String[] args){ 

      System.out.print("Enter: "); 
      int x = input.nextInt(); 
      System.out.print(recurse(x)); 


} 

    public static int recurse(int num){ 

    if(num != 0){ 
    num = num * recurse(num - 1); 
    } else { 
     return 1; 
    } 

    return num; 

} 

}

अगर मैं 25 में प्रवेश, पायथन कोड रिटर्न 1.5511x10E25 है, जो सही जवाब है, लेकिन जावा कोड रिटर्न +२०७६१८०४८०, जो सही जवाब नहीं है, और मुझे यकीन नहीं है कि क्यों।

दोनों कोड एक ही प्रक्रिया के बारे में जाना:

  • जांच करें कि संख्या शून्य
  • है संख्या शून्य
    • num = संख्या संख्या का प्रत्यावर्तन से गुणा नहीं है - 1
  • यदि संख्या शून्य है
    • वापसी 1, रिकर्स कॉल के ढेर को समाप्त करना, और सी हर लौटे संख्या ausing गुणा शुरू करने के लिए
  • वापसी संख्या

अजगर में कोई कोष्ठक हैं; मैंने सोचा कि किसी भी तरह से चीजों को बदल दिया है, इसलिए मैंने जावा कोड से ब्रैकेट हटा दिए, लेकिन यह नहीं बदला। बुलियन को बदलना (num! = 0) से (num> 0) ने कुछ भी नहीं बदला है। किसी और कथन को और अधिक संदर्भ प्रदान करते हुए, लेकिन मान अभी भी वही था।

पायथन:

1 
2 
6 
24 
120 
720 
5040 
40320 
362880 
3628800 
39916800 
479001600 
6227020800 
87178291200 
1307674368000 
20922789888000 
355687428096000 
6402373705728000 
121645100408832000 
2432902008176640000 
51090942171709440000 
1124000727777607680000 
25852016738884976640000 
620448401733239439360000 
15511210043330985984000000 
15511210043330985984000000 

एक स्थिर वृद्धि

हर बिंदु पर संख्या के मूल्यों मुद्रण कैसे समारोह गलत हो जाता है की एक विचार देता है। जावा में:

1 
2 
6 
24 
120 
720 
5040 
40320 
362880 
3628800 
39916800 
479001600 
1932053504 
1278945280 
2004310016 
2004189184 
-288522240 
-898433024 
109641728 
-2102132736 
-1195114496 
-522715136 
862453760 
-775946240 
2076180480 
2076180480 

कोई स्थिर वृद्धि नहीं है। वास्तव में, संख्या नकारात्मक संख्या लौट रही है, भले ही फ़ंक्शन नकारात्मक संख्याएं लौटा रहा हो, भले ही संख्या शून्य से नीचे न हो।

दोनों पायथन और जावा कोड एक ही प्रक्रिया के बारे में जा रहे हैं, फिर भी वे जंगली रूप से अलग-अलग मान लौट रहे हैं। ये क्यों हो रहा है?

+6

इंटीजर ओवरफ़्लो ... – Mysticial

+3

पाइथन int से लंबे समय तक स्वचालित रूप से प्रचार करता है जबकि जावा नहीं करता है। – jamylak

+0

यह एक अच्छा सवाल है कि यह ऐसा कुछ है जहां सभी प्रश्न-उत्तरकर्ता तुरंत समस्या को समझते हैं, लेकिन यह ऐसा कुछ है जिसे आप वास्तव में खोज नहीं सकते हैं जबतक कि आप पहले से ही नहीं जानते कि समस्या क्या कहलाती है। –

उत्तर

11

दो शब्द - पूर्णांक अतिप्रवाह

जबकि अजगर में नहीं एक विशेषज्ञ, मैं इसे अपनी आवश्यकताओं के अनुसार पूर्णांक प्रकार के आकार का विस्तार कर सकते हैं मान।

जावा में, हालांकि, int प्रकार का आकार तय किया गया है - 32 बिट, और int पर हस्ताक्षर किए गए हैं, हमारे पास वास्तव में सकारात्मक संख्याओं का प्रतिनिधित्व करने के लिए केवल 31 बिट हैं। एक बार आपके द्वारा असाइन की गई संख्या अधिकतम से अधिक है, यह int को बहती है (जो है - पूरे नंबर का प्रतिनिधित्व करने के लिए कोई जगह नहीं है)।

सी भाषा में रहते हुए इस तरह के मामले में व्यवहार अनिर्धारित है, जावा में यह अच्छी तरह परिभाषित है, और यह परिणाम के कम से कम 4 बाइट लेता है।

उदाहरण के लिए:

System.out.println(Integer.MAX_VALUE + 1); 
// Integer.MAX_VALUE = 0x7fffffff 

परिणामों में:

-2147483648 
// 0x7fffffff + 1 = 0x800000000 

संपादित

बस इसे स्पष्ट करने के लिए, यहाँ एक और उदाहरण है। निम्नलिखित कोड:

int a = 0x12345678; 
int b = 0x12345678; 
System.out.println("a*b as int multiplication (overflown) [DECIMAL]: " + (a*b)); 
System.out.println("a*b as int multiplication (overflown) [HEX]: 0x" + Integer.toHexString(a*b)); 
System.out.println("a*b as long multiplication (overflown) [DECIMAL]: " + ((long)a*b)); 
System.out.println("a*b as long multiplication (overflown) [HEX]: 0x" + Long.toHexString((long)a*b)); 

आउटपुट:

a*b as int multiplication (overflown) [DECIMAL]: 502585408 
a*b as int multiplication (overflown) [HEX]: 0x1df4d840 
a*b as long multiplication (overflown) [DECIMAL]: 93281312872650816 
a*b as long multiplication (overflown) [HEX]: 0x14b66dc1df4d840 

और आप देख सकते हैं कि दूसरा उत्पादन, पायथन अंतर्निहित 4 उत्पादन

+1

दिलचस्प। क्या आप संदर्भ प्रदान कर सकते हैं? – Zolani13

+0

गंभीरता से, ओपी बताता है कि वह एक नौसिखिया है - यहां थोड़ा और विवरण दें। – kaveman

+1

@ Zolani13 - कृपया संपादित करें देखें। – MByD

2

जावा के विपरीत की कम से कम 4 बाइट्स समर्थन असीमित परिशुद्धता के long integers के लिए। जावा में, एक पूर्णांक 32 बिट तक सीमित है और overflow होगा।

1

जैसा कि पहले से लिखा है, आप अतिप्रवाह प्राप्त करते हैं; संख्याएं जावा के डेटाटाइप प्रतिनिधित्व के भीतर बस फिट नहीं होंगी। पाइथन में बिग्नम की एक अंतर्निहित क्षमता है जहां जावा नहीं है।

कुछ छोटे मानों को आज़माएं और आप देखेंगे कि जावा-कोड ठीक काम करता है।

1

जावा के int रेंज

पूर्णांक 4 बाइट, पर हस्ताक्षर किए (दो का पूरक)। -2,147,483,648 से 2,147,483,647। सभी संख्यात्मक प्रकार की चींटियों की तरह अन्य संख्यात्मक प्रकारों (बाइट, लघु, लंबी, फ्लोट, डबल) में डाली जा सकती है। जब हानिकारक कास्ट किया जाता है (उदाहरण के लिए int से बाइट) रूपांतरण छोटे प्रकार की लंबाई मॉड्यूलो किया जाता है।

यहाँ int की सीमा सीमित है

0

समस्या जावा में बहुत ही सरल ..
coz पूर्णांक की अधिकतम सीमा 2147483647 है यू System.out.println(Integer.MAX_VALUE); से यह मुद्रित कर सकते हैं और कम से कम System.out.println(Integer.MIN_VALUE);

0

क्योंकि है जावा संस्करण में आप संख्या को int के रूप में संग्रहीत करते हैं जो मुझे विश्वास है कि 32-बिट है। बाइनरी में दो बिट्स के साथ स्टोर करने वाले सबसे बड़े (हस्ताक्षरित) नंबर पर विचार करें: 11 जो दशमलव में नंबर 3 है। द्विआधारी में चार बिट्स को संग्रहीत किया जा सकता है सबसे बड़ी संख्या 1111 है जो दशमलव में संख्या 15 है। एक 32-बिट (हस्ताक्षरित) नंबर 2,147,483,647 से बड़ा कुछ भी स्टोर नहीं कर सकता है। जब आप इससे अधिक संख्या को स्टोर करने का प्रयास करते हैं तो यह अचानक वापस घूमता है और नकारात्मक संख्याओं से गिनती शुरू करता है। इसे अतिप्रवाह कहा जाता है।

यदि आप बड़ी संख्या में स्टोर करना चाहते हैं, तो लंबे समय तक प्रयास करें।

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