2011-12-20 14 views
24

कृपया इस टाइप करें।प्रकार, आदि

scala> 86400000 * 150 
res0: Int = 75098112 


scala> val i : Long = 86400000 * 150 
i: Long = 75098112 


val i = 86400000 * 150.asInstanceOf[Long] 
i: Long = 12960000000 

val i = 86400000 * 150L 
i: Long = 12960000000 

क्या दुनिया में यहाँ चल रहा है? मैं स्काइडाइविंग कर रहा हूं और मुझे कहना होगा कि यह सबसे खतरनाक चीज है जिसे मैंने कभी देखा है। इसके लिए कोई कंपाइलर जांच नहीं है? जाहिर है अगर मैं एक चर के लिए 150 प्रतिस्थापित कर रहा था जो अलग है।

* संपादित करें *

यह वास्तविक कोड है कि मुझे चिंतित हो गया था।

val oneDay = 86400000 
val days150 = oneDay * 150 

days150 = 75098112 

यह स्कैला की गलती या किसी के अलावा गलती नहीं थी। बस मुझे चिंतित हो गया।

+13

कृपया इस प्रश्न को वोट मत दें। यह एक वैध सवाल है और पूर्णांक अतिप्रवाह बहुत खतरनाक है और वास्तविक कार्यक्रमों के साथ वास्तविक समस्याएं पैदा करता है। तथ्य यह है कि यह कई भाषाओं में आम है और न केवल स्कैला बल्कि यह इसे कम वोट देता है। –

+1

जब आपको वास्तव में बड़ी संख्या की आवश्यकता होती है, तो हमेशा [बिगइंटर] (http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigInteger.html) होता है। यह थोड़ा गुंजाइश है, लेकिन यह काम करता है। –

+1

बंद करने के लिए वोट दिया; यह एक प्रश्न से अधिक रान है। विभिन्न उदाहरण बताते हैं कि प्रश्नकर्ता पहले से ही जानता है कि क्या हो रहा है: पूर्णांक ओवरफ़्लो। –

उत्तर

15

इस बारे में स्कैला-विशिष्ट कुछ भी नहीं है। यह केवल उस प्रकार के अप्रासंगिक होने के असाइनमेंट के लक्ष्य प्रकार का मामला है जिसमें एक ऑपरेशन (इस मामले में गुणा) किया जाता है।

उदाहरण के लिए, सी # में:

using System; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     int a = unchecked(86400000 * 150); 
     long b = unchecked(86400000 * 150); 
     long c = 86400000 * (long) 150; 
     long d = 86400000 * 150L; 
     Console.WriteLine(a); // 75098112 
     Console.WriteLine(b); // 75098112 
     Console.WriteLine(c); // 12960000000 
     Console.WriteLine(d); // 12960000000 
    } 
} 

क्योंकि सी # संकलक बहुत चालाक एहसास है कि आपरेशन अतिप्रवाह, लेकिन केवल क्योंकि दोनों ऑपरेंड स्थिरांक हैं है unchecked भाग यहाँ है। यदि ऑपरेंड एक वैरिएबल था, तो यह unchecked के बिना ठीक होगा।

जावा में इसी तरह

:

public class Program 
{ 
    public static void main(String[] args) 
    { 
     int a = 86400000 * 150; 
     long b = 86400000 * 150; 
     long c = 86400000 * (long) 150; 
     long d = 86400000 * 150L; 
     System.out.println(a); // 75098112 
     System.out.println(b); // 75098112 
     System.out.println(c); // 12960000000 
     System.out.println(d); // 12960000000 
    } 
} 
+0

इस के लिए धन्यवाद। मैं तो बस किसी कारण के लिए जावा के साथ इस मुद्दे पर ध्यान नहीं किया है। –

+3

दोष सी स्काला और सी # दोनों की नकल की जावा और जावा से उनके निश्चित आकार पूर्णांक नियम मूल रूप से सी ++ जो उन्हें वापस सी –

+4

कौन सा बदले में FORTRAN से उन्हें मिल गया है, जो उन्हें एएसएम से मिला से क्लोन से अपने नियमों की नकल की। उदास।हम एक ऐसे पेशे में हैं जो मेरे पिता के जन्म के समय अस्तित्व में नहीं था और हम प्राचीन ग्रंथों पर टलमूडिक विद्वानों की तरह हैं। – Malvolio

0

यह कोई अंतर्निहित कास्टिंग चल रहा है स्पष्ट है। 86400000 * 150 को int * int के रूप में देखा जाता है, मैं जेवीएम की कल्पना करता हूं। इसकी गणना तब की जाती है जब आप जो भी वैरिएबल टाइप चाहते हैं उसे कोई फर्क नहीं पड़ता। तो करने के लिए सही चीज यह सुनिश्चित करती है कि कम से कम संख्या में से एक या चर को लंबे प्रकार के रूप में डाला जाए, 86400000 * 150.toLong। जेवीएम बड़े प्रकार के लिए डिफ़ॉल्ट रूप से प्रतीत होता है।

बीटीडब्ल्यू, मेरा मानना ​​है कि स्कैला के अंत में ओवरफ्लो चेक केवल प्रदर्शन को अपंग करेगा। तो स्वचालित प्रकार के रूपांतरण की चूक जोखिम को पेश करती है लेकिन बेहतर प्रदर्शन की अनुमति देती है। आपको बस सावधान रहना होगा ..., यदि आप सी/सी ++ बैकअप से आते हैं तो दूसरी प्रकृति होनी चाहिए।

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