क्या "डबल वैल = 1" के बीच अंतर है? और "डबल वैल = 1 डी?"


17

क्या कोड के निम्नलिखित दो टुकड़ों में अंतर है?

class Test {

    public readonly double Val;

    public Test(bool src) {
        this.Val = src ? 1 : 0;
    }

}

class Test {

    public readonly double Val;

    public Test(bool src) {
        this.Val = src ? 1D : 0D;
    }

}

मैंने पाया कि हमारा कोड आधार लेखन के दूसरे तरीके का उपयोग करता है।


मेरे सिर के ऊपर से, पहले एक लंबे समय से डबल पदोन्नति शामिल है।
— तनवीर बदर

2
पहला अंतर्निहित रूपांतरण को दोहरा बनाता है, दूसरा किसी भी रूपांतरण को नहीं बनाता है।
— सर्कन अर्सलन

2
आपका प्रश्न शीर्षक और शरीर में प्रश्न मेल नहीं खाते हैं, और दो प्रश्नों के अलग-अलग उत्तर हैं।
— एरिक लिपर्ट

1
@ एरिक लिपर्ट वास्तव में, सवाल का शरीर अन्य उपयोगकर्ताओं द्वारा संपादित किया गया है।
— srnldai

1
@ ब्रायन: नहीं, मूल पोस्टर सही है; संपादन ने प्रश्न का अर्थ बदल दिया, जिसे मैंने नोटिस नहीं किया। मूल प्रश्न "क्या अंतर है ...? आगे, क्या अंतर है ...?", मेरा जोर। हटाए गए "आगे" इंगित करता है कि मूल पोस्टर को एहसास हुआ कि वे दो सवाल पूछ रहे थे जिनके अलग-अलग जवाब हो सकते हैं। यह एक बुरा अभ्यास है; प्रश्नों को आदर्श रूप से एक ही प्रश्न पूछना चाहिए। लेकिन सम्पादन से ऐसा प्रतीत होता है कि जैसे दो प्रश्नों का उद्देश्य एक ही प्रश्न है, दो अलग-अलग प्रश्न नहीं।
— एरिक लिपर्ट

जवाबों:


18

यहां दो प्रश्न हैं और यह ध्यान रखना महत्वपूर्ण है कि उनके अलग-अलग उत्तर हैं।

क्या आपस में double val = 1;और कोई फर्क है double val = 1D;?

नहीं। C # संकलक पहचानता है कि पूर्णांक शाब्दिक का उपयोग उस संदर्भ में किया जाता है जहां एक डबल की उम्मीद की जाती है और संकलन समय पर प्रकार बदलता है, इसलिए ये दो टुकड़े एक ही कोड उत्पन्न करेंगे।

क्या कोड के निम्नलिखित दो टुकड़ों में अंतर है?

double Val; 
...    
this.Val = src ? 1 : 0;
---
this.Val = src ? 1D : 0D;

हाँ। नियम जो पूर्णांक स्थिरांक स्वचालित रूप से युगल में बदल जाता है , केवल स्थिरांक पर लागू होता है , और src ? ...एक स्थिर नहीं है । कंपाइलर पूर्व को जनरेट करेगा जैसे आपने लिखा था:

int t;
if (src)
  t = 1;
else
  t = 0;
this.Val = (double)t;

और दूसरा के रूप में

double t;
if (src)
  t = 1D;
else
  t = 0D;
this.Val = t;

यही है, पहले में हम एक पूर्णांक चुनते हैं और फिर इसे डबल में परिवर्तित करते हैं, और दूसरे में हम एक डबल चुनते हैं।

FYI करें: C # कंपाइलर या जिटर को यह पहचानने की अनुमति है कि पहले प्रोग्राम को दूसरे में ऑप्टिमाइज़ किया जा सकता है, लेकिन मुझे नहीं पता कि यह वास्तव में ऐसा करता है या नहीं। सी # संकलक कभी-कभी सशर्त रूप से निकाले गए अंकगणित के लिए रूपांतरण को स्थानांतरित करता है ; मैंने वह कोड कुछ आठ साल पहले लिखा था, लेकिन मुझे सभी विवरण याद नहीं हैं।


6

वहाँ है उत्पन्न आईएल कोड में एक फर्क।

यह क्लास:

class Test1
{
    public readonly double Val;

    public Test1(bool src)
    {
        this.Val = src ? 1 : 0;
    }
}

निर्माता के लिए इस IL कोड का उत्पादन करता है:

.class private auto ansi beforefieldinit Demo.Test1
    extends [mscorlib]System.Object
{
    .field public initonly float64 Val

    .method public hidebysig specialname rtspecialname instance void .ctor (
            bool src
        ) cil managed 
    {
        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ldarg.0
        IL_0007: ldarg.1
        IL_0008: brtrue.s IL_000d

        IL_000a: ldc.i4.0
        IL_000b: br.s IL_000e

        IL_000d: ldc.i4.1

        IL_000e: conv.r8
        IL_000f: stfld float64 Demo.Test1::Val
        IL_0014: ret
    }
}

और यह वर्ग:

class Test2
{
    public readonly double Val;

    public Test2(bool src)
    {
        this.Val = src ? 1d : 0d;
    }
}

निर्माता के लिए इस IL कोड का उत्पादन करता है:

.class private auto ansi beforefieldinit Demo.Test2
    extends [mscorlib]System.Object
{
    .field public initonly float64 Val

    .method public hidebysig specialname rtspecialname instance void .ctor (
            bool src
        ) cil managed 
    {
        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ldarg.0
        IL_0007: ldarg.1
        IL_0008: brtrue.s IL_0015

        IL_000a: ldc.r8 0.0
        IL_0013: br.s IL_001e

        IL_0015: ldc.r8 1

        IL_001e: stfld float64 Demo.Test2::Val
        IL_0023: ret
    }
}

जैसा कि आप देख सकते हैं, पहले संस्करण में इसे conv.r8इंट को डबल में बदलने के लिए कॉल करना है।

हालाँकि: (1) अंतिम परिणाम समान है और (2) JIT कंपाइलर इन दोनों को एक ही मशीन कोड में अच्छी तरह से अनुवादित कर सकता है।

तो जवाब है: हाँ, वहाँ है - लेकिन एक है कि आप के बारे में चिंता करने की जरूरत है एक फर्क।

व्यक्तिगत रूप से, मैं दूसरे संस्करण के लिए जाऊंगा क्योंकि यह प्रोग्रामर के इरादे को बेहतर ढंग से व्यक्त करता है, और बहुत ही अधिक कुशल कोड का उत्पादन कर सकता है (जो कि जेआईटी कंपाइलर पर निर्भर करता है)।


4

इसमें कोई अंतर नहीं है, संकलक काफी स्मार्ट है जो कि रूपांतरण करने में सक्षम है या नहीं।
हालांकि, यदि आप उपयोग करते हैं, तो आपको यह सुनिश्चित करने के varलिए लिखना var val = 42D;होगा कि चर एक डबल है और एक इंट नहीं है।

double foo = 1;  // This is a double having the value 1
double bar = 1d; // This is a double having the value 1

var val = 42d;   // This is a double having the value 42
var val2 = 42;   // /!\ This is an int having the value 42 !! /!\
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.