2008-12-23 6 views
23

में डबल से एक्सपोनेंट निकालने क्या मंथिसा और एक्सपोनेंट को सी # (या सामान्य रूप से .NET) में डबल से प्राप्त करने का कोई सीधा तरीका है?मंथिसा निकालने और सी #

मुझे Google का उपयोग करके this example मिला, लेकिन मुझे यकीन नहीं है कि यह कितना मजबूत होगा। ढांचे के कुछ भविष्य के संस्करण में दोहरा परिवर्तन के लिए द्विआधारी प्रतिनिधित्व क्या हो सकता है?

मैंने पाया कि दूसरा विकल्प सिस्टम का उपयोग करना था। डबल के बजाय डेसिमल और उन्हें निकालने के लिए Decimal.GetBits() विधि का उपयोग करना था।

कोई सुझाव?

उत्तर

26

बाइनरी प्रारूप नहीं बदला जाना चाहिए - यह निश्चित रूप से मौजूदा विनिर्देशों में एक तोड़ने वाला परिवर्तन होगा। यह आईईईई 754/आईईसी 605 9 5: 1989 प्रारूप में परिभाषित किया गया है, जिमी ने कहा। (सी # 3.0 भाषा स्पेक सेक्शन 1.3; ईसीएमए 335 सेक्शन 8.2.2)। डबल कनवर्टर में कोड ठीक और मजबूत होना चाहिए।

भविष्य में संदर्भ के लिए, उदाहरण में कोड के प्रासंगिक सा है:

public static string ToExactString (double d) 
{ 
    … 

    // Translate the double into sign, exponent and mantissa. 
    long bits = BitConverter.DoubleToInt64Bits(d); 
    // Note that the shift is sign-extended, hence the test against -1 not 1 
    bool negative = (bits < 0); 
    int exponent = (int) ((bits >> 52) & 0x7ffL); 
    long mantissa = bits & 0xfffffffffffffL; 

    // Subnormal numbers; exponent is effectively one higher, 
    // but there's no extra normalisation bit in the mantissa 
    if (exponent==0) 
    { 
     exponent++; 
    } 
    // Normal numbers; leave exponent as it is but add extra 
    // bit to the front of the mantissa 
    else 
    { 
     mantissa = mantissa | (1L<<52); 
    } 

    // Bias the exponent. It's actually biased by 1023, but we're 
    // treating the mantissa as m.0 rather than 0.m, so we need 
    // to subtract another 52 from it. 
    exponent -= 1075; 

    if (mantissa == 0) 
    { 
     return "0"; 
    } 

    /* Normalize */ 
    while((mantissa & 1) == 0) 
    { /* i.e., Mantissa is even */ 
     mantissa >>= 1; 
     exponent++; 
    } 

    … 
} 

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

+0

यदि मैं सही ढंग से spec को समझता हूं, प्रारूप के दो रूप हैं, एक सामान्य संस्करण और एक सामान्यीकृत संस्करण। कोड का बड़ा हिस्सा अनौपचारिक मंटिसा/एक्सपोनेंट को सामान्यीकृत रूप में परिवर्तित करता है – Jimmy

+0

मुझे "52 अन्य घटाना" भाग नहीं मिलता है। वहाँ क्या चल रहा है? –

+0

@ जे आर: यह समझना थोड़ा मुश्किल है, ईमानदार होने के लिए - टिप्पणी उतनी ही अच्छी नौकरी के बारे में है जितनी मैं सोच सकता हूं। मुझे लगता है कि एक उदाहरण देना सबसे आसान है, लेकिन मुझे डर है कि इस समय मेरा दिमाग तंग हो गया है :( –

1

प्रतिनिधित्व एक आईईईई मानक है और इसे नहीं बदला जाना चाहिए। 1989 (IEEE 754) द्विआधारी फ्लोटिंग प्वाइंट अंकगणित के लिए मानक:

https://msdn.microsoft.com/en-us/library/system.double(v=vs.110).aspx

डबल प्रकार आईईसी 60559 के अनुरूप है।

संपादित करें: दशमलव का कारण क्यों है बिट्स और डबल यह नहीं है कि दशमलव महत्वपूर्ण अंकों को संरक्षित करता है। 3.0000 मीटर == 3.00 मीटर लेकिन एक्सपोनेंट/मंटिस वास्तव में अलग हैं। मुझे लगता है कि फ्लोट/युगल विशिष्ट रूप से प्रतिनिधित्व कर रहे हैं।

+0

सी/सी ++ में एक डबल को 64-बिट्स होने की आवश्यकता नहीं है। मैंने कई प्रणालियों पर काम किया है जहां यह 32-बिट्स है (यानी एक फ्लोट के समान)। सी # अलग है? –

+3

हां, यह 64 बिट्स के रूप में spec में परिभाषित किया गया है। यह सी/सी ++ – Jimmy

+0

@ जिमी में डबल (और लंबे/int/long long) fiasco के बारे में एक अच्छा बिंदु है (या यदि) सी # कम से कम आधे प्लेटफॉर्म का समर्थन करेगा जो सी/सी ++ समर्थन है तो आप सी में फियास्को के बारे में कुछ कह सकते हैं/C++। – Slava

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