अनियंत्रित यूंट के लिए सी # अतिप्रवाह व्यवहार


10

मैं https://dotnetfiddle.net/ पर इस कोड का परीक्षण कर रहा हूं :

using System;

public class Program
{
    const float scale = 64 * 1024;

    public static void Main()
    {
        Console.WriteLine(unchecked((uint)(ulong)(1.2 * scale * scale + 1.5 * scale)));
        Console.WriteLine(unchecked((uint)(ulong)(scale* scale + 7)));
    }
}

अगर मैं .NET 4.7.2 के साथ संकलन करता हूं तो मुझे मिल जाता है

859091763

7

लेकिन अगर मैं रोजलिन या .NET कोर करता हूं, तो मुझे मिलता है

859091763

0

ऐसा क्यों होता है?


ulongबाद के मामले में कलाकारों को नजरअंदाज किया जा रहा है इसलिए यह रूपांतरण float-> intरूपांतरण में हो रहा है ।
23

मैं व्यवहार के परिवर्तन से अधिक आश्चर्यचकित हूं, जो कि बहुत बड़े अंतर की तरह लगता है। मैं उम्मीद नहीं कर सकता कि "0" या तो मान्य जवाब के साथ उस श्रृंखला की tbh है।
लुकास

समझा जा सकता। कंपोजर में कई चीजें तय की गई थीं जब उन्होंने रोजलिन का निर्माण किया, ताकि इसका हिस्सा बन सके। SharpLab पर इस संस्करण पर JIT आउटपुट देखें। यह दर्शाता है कि कलाकार ulongपरिणाम को कैसे प्रभावित करता है।
मध्याह्न

यह आकर्षक है, अपने उदाहरण के साथ डॉटनेटफिल्ड पर, पिछले राइटलाइन आउटपुट 0 में रोजलिन 3.4 और 7 में .NET कोर 3.1
लुकास

मैंने अपने डेस्कटॉप पर भी पुष्टि की। JIT कोड बिल्कुल भी पास नहीं दिखता है, मुझे .NET कोर और .NET फ्रेमवर्क के बीच अलग-अलग परिणाम मिलते हैं। ट्रिपी
लुकास

जवाबों:


1

मेरे निष्कर्ष गलत थे। अधिक जानकारी के लिए अद्यतन देखें।

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

  1. गुणा scaleद्वारा scale, उपजa
  2. प्रदर्शन a + 7, उपजb
  3. डाली b के लिए ulong, उपजc
  4. कास्ट cकियाuint, उपजd

पहले दो ऑपरेशन आपको एक फ्लोट मूल्य के साथ छोड़ देते हैं b = 4.2949673E+09f। मानक फ़्लोटिंग-पॉइंट अंकगणित के तहत, यह है 4294967296( आप इसे यहां देख सकते हैं )। यह ulongठीक है, इसलिए फिट है c = 4294967296, लेकिन यह वास्तव में एक से अधिक है uint.MaxValue, इसलिए यह दौर यात्राएं हैं 0, इसलिए d = 0। अब, आश्चर्य आश्चर्य, फ्लोटिंग प्वाइंट के बाद से गणित फैशनेबल है, 4.2949673E+09fऔर 4.2949673E+09f + 7है आईईईई 754 में ठीक उसी नंबर तो scale * scaleआप एक का एक ही मूल्य दे देंगे floatके रूप मेंscale * scale + 7 , a = bहै, तो दूसरा आपरेशन मूल रूप से एक नहीं सेशन है।

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

मेरा अनुमान है कि आपके द्वारा उपयोग किया जाने वाला .NET 4.7.2 कंपाइलर भी इसे दूर करने का प्रयास करता है, लेकिन इसमें एक बग होता है जिसके कारण यह गलत स्थान पर कलाकारों का मूल्यांकन करता है। स्वाभाविक रूप से, यदि आप पहली बार scaleएक कास्ट uintकरते हैं और फिर ऑपरेशन करते हैं, तो आपको मिलता है 7, क्योंकि scale * scaleराउंड-ट्रिप 0और फिर आप जोड़ते हैं 7। लेकिन यह परिणाम के साथ असंगत है जब आप रन-टाइम पर स्टेप्स-बाय-स्टेप का मूल्यांकन करेंगे । फिर से, मूल कारण सिर्फ एक अनुमान है जब उत्पादित व्यवहार को देखते हुए, लेकिन मैंने जो कुछ ऊपर कहा है, उसे देखते हुए मैं आश्वस्त हूं कि यह पहले संकलक के पक्ष में एक कल्पना का उल्लंघन है।

अपडेट करें:

मैंने नासमझी की है। नहीं है सी # विनिर्देश के इस बिट है कि मैं जब ऊपर जवाब लिख ही अस्तित्व में नहीं पता था:

फ्लोटिंग-पॉइंट ऑपरेशन को ऑपरेशन के परिणाम प्रकार की तुलना में उच्च परिशुद्धता के साथ किया जा सकता है। उदाहरण के लिए, कुछ हार्डवेयर आर्किटेक्चर एक "विस्तारित" या "लॉन्ग डबल" फ्लोटिंग-पॉइंट प्रकार का समर्थन करते हैं, जिसमें डबल रेंज की तुलना में अधिक रेंज और सटीक होता है, और इस उच्च परिशुद्धता प्रकार का उपयोग करके सभी फ्लोटिंग-पॉइंट ऑपरेशन करते हैं। केवल प्रदर्शन में अत्यधिक लागत पर ऐसे हार्डवेयर आर्किटेक्चर को कम सटीकता के साथ फ्लोटिंग-पॉइंट ऑपरेशन करने के लिए बनाया जा सकता है, और इसके बजाय प्रदर्शन और परिशुद्धता दोनों को लागू करने के लिए कार्यान्वयन की आवश्यकता होती है, C # सभी फ़्लोटिंग पॉइंट ऑपरेशन के लिए एक उच्च परिशुद्धता प्रकार का उपयोग करने की अनुमति देता है । अधिक सटीक परिणाम देने के अलावा, इसका शायद ही कोई औसत दर्जे का प्रभाव हो। हालाँकि, प्रपत्र x * y / z, की अभिव्यक्तियों में

सी # कम से कम IEEE 754 के स्तर पर सटीक स्तर प्रदान करने के लिए संचालन की गारंटी देता है , लेकिन जरूरी नहीं कि वास्तव में यही हो। यह बग नहीं है, यह एक विशिष्ट विशेषता है। रोसलिन संकलक वास्तव में आईईईई 754 निर्दिष्ट के रूप में अभिव्यक्ति का मूल्यांकन करने के अपने अधिकार में है, और अन्य संकलक कि अनुमान करने का अधिकार में है 2^32 + 7है 7जब में डाल दिया uint

मुझे अपने पहले भ्रामक उत्तर के लिए खेद है, लेकिन कम से कम हमने आज कुछ सीखा है।


तब मुझे लगता है कि हमारे पास वर्तमान .NET फ्रेमवर्क कंपाइलर में एक बग है (मैंने वीएस 2019 में सिर्फ कोशिश की है कि यह सुनिश्चित हो जाए) :) मुझे लगता है कि मैं यह देखने की कोशिश करूंगा कि क्या बग को लॉग इन करने के लिए कहीं है, हालांकि ऐसा कुछ तय करना। शायद बहुत सारे अवांछित दुष्प्रभाव हैं और शायद इसे नजरअंदाज कर दिया जाए ...
लुकास

मुझे नहीं लगता कि यह समय से पहले कास्टिंग है, कि ए लॉट के मामलों में बहुत स्पष्ट मुद्दों का कारण होगा, मुझे लगता है कि यहां मामला यह है कि कांस्टेबल ऑपरेशन में यह मूल्य का मूल्यांकन नहीं कर रहा है और बहुत अंतिम समय तक कास्टिंग करता है, जिसका अर्थ है यह है कि फ्लोट्स में मध्यवर्ती मूल्यों को संग्रहीत करने के बजाय, यह केवल इसे छोड़ रहा है और प्रत्येक अभिव्यक्ति में इसे स्वयं अभिव्यक्ति के साथ बदल रहा है
jalsh

@ जलश मुझे नहीं लगता कि मैं आपका अनुमान समझता हूं। यदि संकलक ने प्रत्येक scaleको फ्लोट मान के साथ बदल दिया और फिर रनटाइम के दौरान बाकी सब का मूल्यांकन किया, तो परिणाम समान होगा। क्या आप विस्तार से समझा सकते हैं?
V0ldek

@ V0ldek, डाउनवोट एक गलती थी, मैंने आपके उत्तर को संपादित कर दिया ताकि मैं इसे हटा
सकूं

मेरा अनुमान है कि यह वास्तव में फ्लोट्स में मध्यवर्ती मूल्यों को संग्रहीत नहीं करता था, यह सिर्फ एफ की अभिव्यक्ति के साथ बदल दिया गया है जो इसे फ्लोट करने के लिए कास्टिंग के बिना मूल्यांकन करता है
जल्श

0

यहाँ बिंदु (जैसा कि आप डॉक्स पर देख सकते हैं ) है कि फ्लोट मान केवल 2 ^ 24 तक का आधार हो सकता है । इसलिए, जब आप 2 ^ 32 ( 64 * 2014 * 164 * 1024 = 2 ^ 6 * 2 ^ 10 * 2 ^ 6 * 2 ^ 10 = 2 ^ 32 ) का मान असाइन करते हैं, तो यह वास्तव में 2 ^ 24 * 2 ^ हो जाता है। 8 , जो 4294967000 है7 जोड़ना केवल रूपांतरण द्वारा काटे गए भाग में जोड़ना होगा Ulong

यदि आप डबल में बदलते हैं , जिसका आधार है 2 ^ 53 है , तो यह आपके इच्छित काम करेगा।

यह एक रन-टाइम मुद्दा हो सकता है, लेकिन इस मामले में, यह एक संकलन-समय का मुद्दा है, क्योंकि सभी मान स्थिर हैं और संकलक द्वारा मूल्यांकन किया जाएगा।


-2

सबसे पहले आप अनियंत्रित संदर्भ का उपयोग कर रहे हैं जो कि एक कंपाइलर के लिए एक निर्देश है जो आपको एक डेवलपर के रूप में सुनिश्चित करता है, कि परिणाम ओवरफ्लो नहीं होगा और आप कोई संकलन त्रुटि नहीं देखना चाहेंगे। आपके परिदृश्य में आप वास्तव में उद्देश्य से अधिक प्रकार के हैं और तीन अलग-अलग कंपाइलरों में लगातार व्यवहार की अपेक्षा कर रहे हैं, जिनमें से एक रोसेलिन और .NET कोर की तुलना में इतिहास में संभवतः सबसे पिछड़ा संगत है जो नए हैं।

दूसरी बात यह है कि आप अंतर्निहित और स्पष्ट रूपांतरणों का मिश्रण कर रहे हैं। मैं रोज़लिन कंपाइलर के बारे में निश्चित नहीं हूं, लेकिन निश्चित रूप से .NET फ्रेमवर्क और .NET कोर कंपाइलर्स उन ऑपरेशनों के लिए अलग-अलग अनुकूलन का उपयोग कर सकते हैं।

यहां समस्या यह है कि आपके कोड की पहली पंक्ति केवल फ्लोटिंग पॉइंट वैल्यू / प्रकार का उपयोग करती है, लेकिन दूसरी लाइन फ्लोटिंग पॉइंट वैल्यू / टाइप और इंटीग्रल वैल्यू / टाइप का संयोजन है।

यदि आप पूर्णांक फ़्लोटिंग पॉइंट टाइप बनाते हैं तो सीधे (7> 7.0) आप तीनों संकलित स्रोतों के लिए एक ही परिणाम प्राप्त करेंगे।

using System;

public class Program
{
    const float scale = 64 * 1024;

    public static void Main()
    {
        Console.WriteLine(unchecked((uint)(ulong)(1.2 * scale * scale + 1.5 * scale))); // 859091763
        Console.WriteLine(unchecked((uint)(ulong)(scale * scale + 7.0))); // 7
    }
}

इसलिए, मैं इसके विपरीत कहूंगा कि V0ldek ने जो जवाब दिया और वह यह है कि "द बग (यदि यह वास्तव में एक बग है) रोसेलिन और .NET कोर कंपाइलर्स में सबसे अधिक संभावना है"।

यह मानने का एक और कारण यह है कि पहले अनियंत्रित संगणना के परिणाम सभी के लिए समान होते हैं और यह मान है कि अधिकतम UInt32प्रकार का अधिकतम मान होता है ।

Console.WriteLine(unchecked((uint)(ulong)(1.2 * scale * scale + 1.5 * scale) - UInt32.MaxValue - 1)); // 859091763

माइनस एक वहाँ है क्योंकि हम शून्य से शुरू करते हैं जो मूल्य है जो खुद को घटाना मुश्किल है। यदि अतिप्रवाह की मेरी गणित समझ सही है तो हम अधिकतम मान के बाद अगले नंबर से शुरू करते हैं।

अपडेट करें

जलश टिप्पणी के अनुसार

7.0 एक डबल है, फ्लोट नहीं है, 7.0f की कोशिश करें, यह अभी भी आपको 0 देगा

उनकी टिप्पणी सही है। यदि हम फ्लोट का उपयोग करते हैं तो आपको रोजलिन और .NET कोर के लिए 0 मिलता है, लेकिन दूसरी ओर 7 में दोहरे परिणाम का उपयोग करते हुए।

मैंने कुछ अतिरिक्त परीक्षण किए और चीजें भी अजीब हो गईं, लेकिन अंत में सब कुछ समझ में आता है (कम से कम थोड़ा)।

मेरा मानना ​​है कि .NET फ्रेमवर्क 4.7.2 कंपाइलर (2018 के मध्य में जारी किया गया) वास्तव में .NET कोर 3.1 और रोसलिन 3.4 कंपाइलर (2019 के अंत में जारी) की तुलना में अलग-अलग अनुकूलन का उपयोग करता है। ये विभिन्न अनुकूलन / संगणनाएँ विशुद्ध रूप से संकलन-समय पर ज्ञात निरंतर मूल्यों के लिए उपयोग की जाती हैं। यही कारण है कि uncheckedकीवर्ड का उपयोग करने की आवश्यकता थी क्योंकि संकलक को पहले से ही पता है कि अतिप्रवाह हो रहा है, लेकिन अंतिम आईएल को अनुकूलित करने के लिए अलग-अलग गणना का उपयोग किया गया था।

समान स्रोत कोड और IL_000a निर्देश को छोड़कर लगभग समान IL। एक कंपाइलर 7 और अन्य 0 की गणना करता है।

सोर्स कोड

using System;

public class Program
{
    const float scale = 64 * 1024;

    public static void Main()
    {
        Console.WriteLine(unchecked((uint)(ulong)(1.2 * scale * scale + 1.5 * scale)));
        Console.WriteLine(unchecked((uint)(scale * scale + 7.0)));
    }
}

.NET फ्रेमवर्क (x64) आईएल

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit Program
    extends [mscorlib]System.Object
{
    // Fields
    .field private static literal float32 scale = float32(65536)

    // Methods
    .method public hidebysig static 
        void Main () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 17 (0x11)
        .maxstack 8

        IL_0000: ldc.i4 859091763
        IL_0005: call void [mscorlib]System.Console::WriteLine(uint32)
        IL_000a: ldc.i4.7
        IL_000b: call void [mscorlib]System.Console::WriteLine(uint32)
        IL_0010: ret
    } // end of method Program::Main

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x2062
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    } // end of method Program::.ctor

} // end of class Program

रोजलिन कंपाइलर शाखा (सितंबर 2019) आईएल

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit Program
    extends [System.Private.CoreLib]System.Object
{
    // Fields
    .field private static literal float32 scale = float32(65536)

    // Methods
    .method public hidebysig static 
        void Main () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 17 (0x11)
        .maxstack 8

        IL_0000: ldc.i4 859091763
        IL_0005: call void [System.Console]System.Console::WriteLine(uint32)
        IL_000a: ldc.i4.0
        IL_000b: call void [System.Console]System.Console::WriteLine(uint32)
        IL_0010: ret
    } // end of method Program::Main

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x2062
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
        IL_0006: ret
    } // end of method Program::.ctor

} // end of class Program

जब आप uncheckedनीचे की तरह गैर-स्थिर अभिव्यक्ति (डिफ़ॉल्ट रूप से ) जोड़ते हैं तो यह सही तरीके से जाना शुरू कर देता है ।

using System;

public class Program
{
    static Random random = new Random();

    public static void Main()
    {
        var scale = 64 * random.Next(1024, 1025);       
        uint f = (uint)(ulong)(scale * scale + 7f);
        uint d = (uint)(ulong)(scale * scale + 7d);
        uint i = (uint)(ulong)(scale * scale + 7);

        Console.WriteLine((uint)(ulong)(1.2 * scale * scale + 1.5 * scale)); // 859091763
        Console.WriteLine((uint)(ulong)(scale * scale + 7f)); // 7
        Console.WriteLine(f); // 7
        Console.WriteLine((uint)(ulong)(scale * scale + 7d)); // 7
        Console.WriteLine(d); // 7
        Console.WriteLine((uint)(ulong)(scale * scale + 7)); // 7
        Console.WriteLine(i); // 7
    }
}

जो दोनों कंपाइलरों द्वारा "बिल्कुल" समान आईएल उत्पन्न करता है।

.NET फ्रेमवर्क (x64) आईएल

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit Program
    extends [mscorlib]System.Object
{
    // Fields
    .field private static class [mscorlib]System.Random random

    // Methods
    .method public hidebysig static 
        void Main () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 164 (0xa4)
        .maxstack 4
        .locals init (
            [0] int32,
            [1] uint32,
            [2] uint32
        )

        IL_0000: ldc.i4.s 64
        IL_0002: ldsfld class [mscorlib]System.Random Program::random
        IL_0007: ldc.i4 1024
        IL_000c: ldc.i4 1025
        IL_0011: callvirt instance int32 [mscorlib]System.Random::Next(int32, int32)
        IL_0016: mul
        IL_0017: stloc.0
        IL_0018: ldloc.0
        IL_0019: ldloc.0
        IL_001a: mul
        IL_001b: conv.r4
        IL_001c: ldc.r4 7
        IL_0021: add
        IL_0022: conv.u8
        IL_0023: conv.u4
        IL_0024: ldloc.0
        IL_0025: ldloc.0
        IL_0026: mul
        IL_0027: conv.r8
        IL_0028: ldc.r8 7
        IL_0031: add
        IL_0032: conv.u8
        IL_0033: conv.u4
        IL_0034: stloc.1
        IL_0035: ldloc.0
        IL_0036: ldloc.0
        IL_0037: mul
        IL_0038: ldc.i4.7
        IL_0039: add
        IL_003a: conv.i8
        IL_003b: conv.u4
        IL_003c: stloc.2
        IL_003d: ldc.r8 1.2
        IL_0046: ldloc.0
        IL_0047: conv.r8
        IL_0048: mul
        IL_0049: ldloc.0
        IL_004a: conv.r8
        IL_004b: mul
        IL_004c: ldc.r8 1.5
        IL_0055: ldloc.0
        IL_0056: conv.r8
        IL_0057: mul
        IL_0058: add
        IL_0059: conv.u8
        IL_005a: conv.u4
        IL_005b: call void [mscorlib]System.Console::WriteLine(uint32)
        IL_0060: ldloc.0
        IL_0061: ldloc.0
        IL_0062: mul
        IL_0063: conv.r4
        IL_0064: ldc.r4 7
        IL_0069: add
        IL_006a: conv.u8
        IL_006b: conv.u4
        IL_006c: call void [mscorlib]System.Console::WriteLine(uint32)
        IL_0071: call void [mscorlib]System.Console::WriteLine(uint32)
        IL_0076: ldloc.0
        IL_0077: ldloc.0
        IL_0078: mul
        IL_0079: conv.r8
        IL_007a: ldc.r8 7
        IL_0083: add
        IL_0084: conv.u8
        IL_0085: conv.u4
        IL_0086: call void [mscorlib]System.Console::WriteLine(uint32)
        IL_008b: ldloc.1
        IL_008c: call void [mscorlib]System.Console::WriteLine(uint32)
        IL_0091: ldloc.0
        IL_0092: ldloc.0
        IL_0093: mul
        IL_0094: ldc.i4.7
        IL_0095: add
        IL_0096: conv.i8
        IL_0097: conv.u4
        IL_0098: call void [mscorlib]System.Console::WriteLine(uint32)
        IL_009d: ldloc.2
        IL_009e: call void [mscorlib]System.Console::WriteLine(uint32)
        IL_00a3: ret
    } // end of method Program::Main

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x2100
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    } // end of method Program::.ctor

    .method private hidebysig specialname rtspecialname static 
        void .cctor () cil managed 
    {
        // Method begins at RVA 0x2108
        // Code size 11 (0xb)
        .maxstack 8

        IL_0000: newobj instance void [mscorlib]System.Random::.ctor()
        IL_0005: stsfld class [mscorlib]System.Random Program::random
        IL_000a: ret
    } // end of method Program::.cctor

} // end of class Program

रोजलिन कंपाइलर शाखा (सितंबर 2019) आईएल

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit Program
    extends [System.Private.CoreLib]System.Object
{
    // Fields
    .field private static class [System.Private.CoreLib]System.Random random

    // Methods
    .method public hidebysig static 
        void Main () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 164 (0xa4)
        .maxstack 4
        .locals init (
            [0] int32,
            [1] uint32,
            [2] uint32
        )

        IL_0000: ldc.i4.s 64
        IL_0002: ldsfld class [System.Private.CoreLib]System.Random Program::random
        IL_0007: ldc.i4 1024
        IL_000c: ldc.i4 1025
        IL_0011: callvirt instance int32 [System.Private.CoreLib]System.Random::Next(int32, int32)
        IL_0016: mul
        IL_0017: stloc.0
        IL_0018: ldloc.0
        IL_0019: ldloc.0
        IL_001a: mul
        IL_001b: conv.r4
        IL_001c: ldc.r4 7
        IL_0021: add
        IL_0022: conv.u8
        IL_0023: conv.u4
        IL_0024: ldloc.0
        IL_0025: ldloc.0
        IL_0026: mul
        IL_0027: conv.r8
        IL_0028: ldc.r8 7
        IL_0031: add
        IL_0032: conv.u8
        IL_0033: conv.u4
        IL_0034: stloc.1
        IL_0035: ldloc.0
        IL_0036: ldloc.0
        IL_0037: mul
        IL_0038: ldc.i4.7
        IL_0039: add
        IL_003a: conv.i8
        IL_003b: conv.u4
        IL_003c: stloc.2
        IL_003d: ldc.r8 1.2
        IL_0046: ldloc.0
        IL_0047: conv.r8
        IL_0048: mul
        IL_0049: ldloc.0
        IL_004a: conv.r8
        IL_004b: mul
        IL_004c: ldc.r8 1.5
        IL_0055: ldloc.0
        IL_0056: conv.r8
        IL_0057: mul
        IL_0058: add
        IL_0059: conv.u8
        IL_005a: conv.u4
        IL_005b: call void [System.Console]System.Console::WriteLine(uint32)
        IL_0060: ldloc.0
        IL_0061: ldloc.0
        IL_0062: mul
        IL_0063: conv.r4
        IL_0064: ldc.r4 7
        IL_0069: add
        IL_006a: conv.u8
        IL_006b: conv.u4
        IL_006c: call void [System.Console]System.Console::WriteLine(uint32)
        IL_0071: call void [System.Console]System.Console::WriteLine(uint32)
        IL_0076: ldloc.0
        IL_0077: ldloc.0
        IL_0078: mul
        IL_0079: conv.r8
        IL_007a: ldc.r8 7
        IL_0083: add
        IL_0084: conv.u8
        IL_0085: conv.u4
        IL_0086: call void [System.Console]System.Console::WriteLine(uint32)
        IL_008b: ldloc.1
        IL_008c: call void [System.Console]System.Console::WriteLine(uint32)
        IL_0091: ldloc.0
        IL_0092: ldloc.0
        IL_0093: mul
        IL_0094: ldc.i4.7
        IL_0095: add
        IL_0096: conv.i8
        IL_0097: conv.u4
        IL_0098: call void [System.Console]System.Console::WriteLine(uint32)
        IL_009d: ldloc.2
        IL_009e: call void [System.Console]System.Console::WriteLine(uint32)
        IL_00a3: ret
    } // end of method Program::Main

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x2100
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
        IL_0006: ret
    } // end of method Program::.ctor

    .method private hidebysig specialname rtspecialname static 
        void .cctor () cil managed 
    {
        // Method begins at RVA 0x2108
        // Code size 11 (0xb)
        .maxstack 8

        IL_0000: newobj instance void [System.Private.CoreLib]System.Random::.ctor()
        IL_0005: stsfld class [System.Private.CoreLib]System.Random Program::random
        IL_000a: ret
    } // end of method Program::.cctor

} // end of class Program

इसलिए, अंत में मेरा मानना ​​है कि विभिन्न व्यवहार का कारण रूपरेखा और / या संकलक का एक अलग संस्करण है जो निरंतर अभिव्यक्तियों के लिए अलग-अलग अनुकूलन / संगणना का उपयोग कर रहे हैं, लेकिन अन्य मामलों में व्यवहार बहुत ही समान है।


7.0 एक डबल है, फ्लोट नहीं है, 7.0f की कोशिश करें, यह अभी भी आपको 0
jalsh

हां, यह फ्लोटिंग पॉइंट टाइप होना चाहिए, फ्लोट नहीं। सुधार के लिए धन्यवाद।
ड्रॉपआउटकोडर

यह समस्या के पूरे परिप्रेक्ष्य को बदल देता है, जब आपके द्वारा प्राप्त की जा रही सटीकता से दोगुने से निपटना अधिक होता है और V0ldek के उत्तर में दिए गए परिणाम में बहुत अधिक परिवर्तन होता है, तो आप केवल पैमाने को फिर से दोगुना और फिर से जांच सकते हैं, परिणाम समान होंगे। ..
जलश

अंत में यह अधिक जटिल मुद्दा है।
dropoutcoder

1
@ जलेश हां, लेकिन एक संकलक ध्वज है जो हर जगह जांचे गए संदर्भ को बदल देता है। आप सुरक्षा के लिए सब कुछ जाँचने के लिए चाहते हो सकते हैं, सिवाय एक निश्चित गर्म मार्ग के जिसे सभी सीपीयू चक्रों की आवश्यकता होती है।
V0ldek
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.