पूर्णांक विभाजन: आप एक दोहरे उत्पादन कैसे करते हैं?


249

इस कोड ब्लॉक के लिए:

int num = 5;
int denom = 7;
double d = num / denom;

का मूल्य dहै 0.0। यह कास्टिंग द्वारा काम करने के लिए मजबूर किया जा सकता है:

double d = ((double) num) / denom;

लेकिन क्या सही doubleपरिणाम प्राप्त करने का एक और तरीका है ? मुझे कास्टिंग प्रिमिटिव्स पसंद नहीं हैं, जो जानते हैं कि क्या हो सकता है।



9
डबल करने के लिए 'इंट' डालना सुरक्षित है, आपको हमेशा सटीक नुकसान के बिना समान मूल्य मिलेगा।
पीटर लॉरी

1
मैं यह जानना चाहूंगा कि क्या संभाग के लिए संकलक द्वारा उठाए गए सही कदम हैं: 1) फ्लोट करने के लिए कास्ट संख्या 2) कास्ट डिनोम को फ्लोट के रूप में अच्छी तरह से 2) क्रॉम को विभाजित करें। कृपया मुझे बताएं कि क्या मैं गलत हूं।
2

जवाबों:


156
double num = 5;

जो एक डाली से बचता है। लेकिन आप पाएंगे कि कलाकारों के रूपांतरण अच्छी तरह से परिभाषित हैं। आपको अनुमान लगाने की जरूरत नहीं है, बस जेएलएस की जांच करें । इंट टू डबल एक व्यापक रूपांतरण है। से §5.1.2 :

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

[...]

एक अंतर या लंबे मान के तैरने के लिए या लंबे समय के मूल्य को दोगुना करने का परिणाम सटीक-हानि का परिणाम हो सकता है, जिसके परिणामस्वरूप मूल्य के कम से कम महत्वपूर्ण बिट्स खो सकते हैं। इस मामले में, परिणामी फ्लोटिंग-पॉइंट वैल्यू IEEE 754 राउंड-टू-निकटतम मोड (§4.2.4) का उपयोग करके पूर्णांक मान का एक सही रूप से गोल संस्करण होगा ।

5 को एक डबल के रूप में बिल्कुल व्यक्त किया जा सकता है।


60
+1। कास्टिंग से डरना बंद करें। जानें कि यह कैसे काम करता है। यह सब अच्छी तरह से परिभाषित है।
मार्क पीटर्स 21

1
@ फ़ाइब्रिओहॉफ़ यह हर स्थिति में काम करता है, और पहचान के लिए * 1.0 समाधान।
विट्रुवियस

3
@ सपोशिएंट यह काम करने से परे है या नहीं। चर का प्रकार बदलना मुझे गंदा कोड लगता है। यदि आपके पास कुछ ऐसा है जो एक पूर्णांक होना जरूरी है और आप केवल एक फ्लोट के लिए प्रतिनिधित्व को बदलते हैं तो गणित ऑपरेशन करने में सक्षम होने के लिए, आप खुद को जोखिम में डाल सकते हैं। इसके अलावा कुछ संदर्भ में चर को पूर्णांक के रूप में पढ़ना कोड को समझना आसान बनाता है।
फैब्रिकियो PH

2
@FabricioPH, 1.0अभी भी गुणा करके परिणाम का प्रकार बदलता है, बस एक अलग तरीके से। 'मुझे गंदा कोड लगता है' यह नहीं समझाता है कि आप किस परिदृश्य में विश्वास करते हैं कि 1.0वास्तव में गुणा करना बेहतर है (या ऐसा क्यों हो सकता है)।
मैथ्यू फ्लैशेन

4
@ फैब्रिकॉफ़ आप और ओपी झूठे विश्वास (जहाँ आप कहते हैं कि "परिवर्तनशील के प्रकार को बदलना") के तहत श्रम करना प्रतीत होता है, जो (double)numकिसी तरह बदल जाता है num। ऐसा नहीं है - यह कथन के संदर्भ के लिए एक अस्थायी डबल बनाता है।
पॉल टॉम्बलिन

100

कास्टिंग प्रिमिटिव्स में क्या गलत है?

यदि आप किसी कारण से नहीं चाहते हैं, तो आप कर सकते हैं

double d = num * 1.0 / denom;

63
... जो गुणन से पहले एक निहित कास्ट करता है
एलिस पुरसेल

2
ज्यादातर मामलों में यह अन्य चर के प्रकार को बदलने से बेहतर है।
फैब्रिकियो PH

3
@FabricioPH कुछ भी नहीं यह सच होने का सुझाव देता है, जब तक कि आपके पास स्रोत का हवाला न हो।
विट्रुवियस

1
@Saposhiente अपने अन्य इसी तरह के टिप्पणी में उत्तर दिया
फ़ेब्रिकियो पीएच

1
आप "डी" पोस्टफिक्स (उसी निहित कलाकारों को निष्पादित करने के लिए) का भी उपयोग कर सकते हैं; - तो उदाहरण के लिए:double d = num * 1D / denom;
BrainSlugs83

73

मुझे कास्टिंग प्रिमिटिव्स पसंद नहीं हैं, जो जानते हैं कि क्या हो सकता है।

आपको कास्टिंग प्रीमिटिव्स का तर्कहीन डर क्यों है? जब आप एक intको कास्ट करते हैं तो कुछ भी बुरा नहीं होगा double। यदि आप यह सुनिश्चित नहीं करते हैं कि यह कैसे काम करता है, तो इसे जावा भाषा विनिर्देश में देखें । एक कास्टिंग intके लिए doubleएक है चौड़ा करने आदिम रूपांतरण

आप अंश के बजाय हर को कास्टिंग करके कोष्ठक की अतिरिक्त जोड़ी से छुटकारा पा सकते हैं:

double d = num / (double) denom;

2
आप यह भी कर सकते हैं double d = (double) num / denom;... (ठीक है, यह एक पूर्वता पर निर्भर करता है)
user85421

27

यदि आप एक सूत्र के प्रकार को बदलते हैं जिसे आपको अपने फार्मूले में बदलने के लिए फिर से एक डबल में चुपके से याद रखना होगा, क्योंकि यदि यह चर गणना के भाग के रूप में बंद हो जाता है तो परिणाम गड़बड़ हो जाता है। मुझे गणना के भीतर कास्टिंग करने की आदत है, और इसके आगे एक टिप्पणी जोड़ें।

double d = 5 / (double) 20; //cast to double, to do floating point calculations

ध्यान दें कि परिणाम कास्ट करना ऐसा नहीं करेगा

double d = (double)(5 / 20); //produces 0.0

17

फ्लोटिंग पॉइंट मैथ के साथ किए जाने वाले ऑपरेशन को बाध्य करने के लिए पूर्णांक / पूर्णांक के दोनों में से एक कास्ट करें। अन्यथा पूर्णांक गणित हमेशा पसंद किया जाता है। इसलिए:

1. double d = (double)5 / 20;
2. double v = (double)5 / (double) 20;
3. double v = 5 / (double) 20;

ध्यान दें कि परिणाम कास्ट करना ऐसा नहीं करेगा। क्योंकि पहले विभाजन को पूर्ववर्ती नियम के अनुसार किया जाता है।

double d = (double)(5 / 20); //produces 0.0

मुझे नहीं लगता कि कास्टिंग को लेकर कोई समस्या है जैसे आप सोच रहे हैं।


10

टाइप कास्टिंग केवल एकमात्र तरीका है


एक निर्माण doubleपूर्णांक से division- बिना कोई दूसरा रास्ता नहीं है कास्टिंग (आप इसे स्पष्ट रूप से काम नहीं चलेगा हो सकता है लेकिन यह होगा)।

अब, वहाँ कई तरीके हम सटीक प्राप्त करने की कोशिश कर सकते हैं doubleमूल्य (जहां numऔर denomकर रहे हैं intप्रकार, और के पाठ्यक्रम कास्टिंग के साथ ) -

  1. स्पष्ट कास्टिंग के साथ:

    • double d = (double) num / denom;
    • double d = ((double) num) / denom;
    • double d = num / (double) denom;
    • double d = (double) num / (double) denom;

लेकिन नहीं double d = (double) (num / denom);

  1. अंतर्निहित कास्टिंग के साथ:

    • double d = num * 1.0 / denom;
    • double d = num / 1d / denom;
    • double d = ( num + 0.0 ) / denom;
    • double d = num; d /= denom;

लेकिन नहीं double d = num / denom * 1.0;
और नहींdouble d = 0.0 + ( num / denom );



0

आप संचालन को लपेटने पर विचार कर सकते हैं। उदाहरण के लिए:

class Utils
{
    public static double divide(int num, int denom) {
        return ((double) num) / denom;
    }
}

यह आपको ऊपर (बस एक बार) देखने की अनुमति देता है कि क्या कलाकार वास्तव में वही चाहता है जो आप चाहते हैं। यह विधि परीक्षणों के अधीन भी हो सकती है, यह सुनिश्चित करने के लिए कि यह वही करना जारी रखे जो आप चाहते हैं। यह भी मायने नहीं रखता है कि आप विभाजन के कारण किस चाल का उपयोग करते हैं (आप यहां किसी भी उत्तर का उपयोग कर सकते हैं), जब तक कि यह सही परिणाम नहीं देता है। कहीं भी आपको दो पूर्णांकों को विभाजित करने की आवश्यकता होती है, अब आप बस कॉल कर सकते हैं Utils::divideऔर भरोसा कर सकते हैं कि यह सही काम करता है।



हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.