2012-08-08 21 views
7

वापस करने के लिए बिगइंटर को विभाजित करना मैं एक रेखा की ढलान की गणना करना चाहता हूं।डबल

public sealed class Point 
{ 
    public System.Numerics.BigInteger x = 0; 
    public System.Numerics.BigInteger y = 0; 

    public double CalculateSlope (Point point) 
    { 
     return ((point.Y - this.Y)/(point.X - this.X)); 
    } 
} 

मुझे पता है कि BigInteger एक DivRem समारोह है कि विभाजन परिणाम प्लस शेष रिटर्न लेकिन यकीन है कि यह कैसे लागू करने के लिए एक डबल पाने के लिए नहीं कर रहा हूँ है। जिन नंबरों के साथ मैं काम कर रहा हूं वे दूर हैं इंट 64 की सीमा से परे। मैक्सवेल्यू इसलिए शेष भाग पारंपरिक विभाजन द्वारा गणना करने के लिए सीमा से बाहर हो सकता है।

EDIT: सुनिश्चित नहीं है कि यह मदद करता है लेकिन मैं केवल सकारात्मक पूर्णांक (> = 1) से निपट रहा हूं।

महत्वपूर्ण: मुझे केवल परिशुद्धता के कुछ दशमलव बिंदु चाहिए (5 मेरे उद्देश्य के लिए पर्याप्त होना चाहिए)।

+0

आपको यह कितना सटीक होना चाहिए? –

+0

आप जिन संख्याओं से निपट रहे हैं, वे संख्याएं – MethodMan

+0

@ ऑस्टिनसलोलेन: सटीक परिशुद्धता जितनी अधिक होगी, सटीकता के कुछ दशमलव अंक भी मुझे प्राप्त करने के लिए पर्याप्त होंगे। –

उत्तर

5

BigRational लाइब्रेरी में एक रूपांतरण ऑपरेटर डबल है।

इसके अलावा, एक लंबवत रेखा के लिए एक विशेष मामले के रूप में अनंतता वापस लौटना याद रखें, आपको अपने वर्तमान कोड के साथ शून्य अपवाद द्वारा विभाजित किया जाएगा। शायद एक्स 1 - एक्स 2 की गणना करने के लिए शायद सबसे अच्छा है, और शून्य होने पर अनंतता लौटाएं, फिर अनावश्यक संचालन से बचने के लिए विभाजन करें।

+0

दिलचस्प। यह कक्षा .NET 4 में मौजूद नहीं है? यदि यह बीटा या रिलीज उम्मीदवार है, तो दुर्भाग्य से मैं इसे उत्पादन कोड में उपयोग नहीं कर सकता। –

+0

यह एक बीटा है। आप इसका उपयोग क्यों नहीं कर सकते? – Random832

+0

यह एक उत्पादन आवेदन के लिए है। गुणवत्ता आश्वासन बीटा पुस्तकालयों की अनुमति नहीं देता है। –

1

यह नकारात्मक से निपटता नहीं है लेकिन उम्मीद है कि आपको शुरुआत होगी।

 double doubleMax = double.MaxValue; 
     BigInteger numerator = 120; 
     BigInteger denominator = 50;   
     if (denominator != 0) 
     { 
      Debug.WriteLine(numerator/denominator); 
      Debug.WriteLine(numerator % denominator); 
      BigInteger ansI = numerator/denominator; 
      if (ansI < (int)doubleMax) 
      { 
       double slope = (double)ansI + ((double)(numerator % denominator)/(double)denominator); ; 
       Debug.WriteLine(slope); 
      } 
     } 
+0

धन्यवाद। हालांकि, यह केवल तभी काम करेगा जब अभिन्न परिणाम Int32 या UInt64 के भीतर उस मामले के लिए है। एन 3 को विभाजित करने के बारे में सोचें जहां एन में 10,000,000 अंक हैं। –

+0

@ राहेलखन बिल्कुल। सवाल सार्वजनिक डबल गणना स्लोप पढ़ें। यदि डबल से बड़ा है तो उत्तर को दोगुना नहीं किया जा सकता है। – Paparazzi

+0

बेशक। ढलान हमेशा -1.0 और 1.0 के बीच होगा। यह सटीकता है कि एक बड़े तरीके से खो जा रहा है। –

4

कोडप्लेक्स से BigRational प्राप्त करें। माइक्रोसॉफ्ट के Base Class Library का इसका हिस्सा, इसलिए यह नेट के लिए एक प्रगति-प्रगति है। अपरिहार्य अतिप्रवाह/अधःप्रवाह/परिशुद्धता है, ज़ाहिर है, एक और समस्या के नुकसान के साथ काम

System.Numerics.BigInteger x = GetDividend() ; 
System.Numerics.BigInteger y = GetDivisor() ; 

BigRational r  = new BigRational(x , y) ; 
double  value = (double) r ; 

: एक बार आपको लगता है कि है, तो कुछ इस तरह से करते हैं।

चूंकि आप अपने कोड में BigRational पुस्तकालय ड्रॉप नहीं कर सकते, जाहिर है, अन्य दृष्टिकोण "रोलिंग की

आसान तरीका right algorithms book बाहर निकलने के लिए और अपने खुद के रोल ..., ज़ाहिर है, हो सकता है एक का अपना "यहां, चूंकि एक तर्कसंगत संख्या को दो पूर्णांक के अनुपात (विभाजन) के रूप में दर्शाया गया है, इसलिए बिगरेनल क्लास से डबल ऑपरेटर को स्पष्ट रूपांतरण प्राप्त करना है और इसे सूट करने के लिए ट्विक करना है। मुझे लगभग 15 मिनट लग गए।

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

public static class BigIntExtensions 
{ 

    public static double DivideAndReturnDouble(this BigInteger x , BigInteger y) 
    { 
    // The Double value type represents a double-precision 64-bit number with 
    // values ranging from -1.79769313486232e308 to +1.79769313486232e308 
    // values that do not fit into this range are returned as +/-Infinity 
    if (SafeCastToDouble(x) && SafeCastToDouble(y)) 
    { 
     return (Double) x/(Double) y; 
    } 

    // kick it old-school and figure out the sign of the result 
    bool isNegativeResult = ((x.Sign < 0 && y.Sign > 0) || (x.Sign > 0 && y.Sign < 0)) ; 

    // scale the numerator to preseve the fraction part through the integer division 
    BigInteger denormalized = (x * s_bnDoublePrecision)/y ; 
    if (denormalized.IsZero) 
    { 
     return isNegativeResult ? BitConverter.Int64BitsToDouble(unchecked((long)0x8000000000000000)) : 0d; // underflow to -+0 
    } 

    Double result = 0    ; 
    bool isDouble = false   ; 
    int scale = DoubleMaxScale ; 

    while (scale > 0) 
    { 
     if (!isDouble) 
     { 
     if (SafeCastToDouble(denormalized)) 
     { 
      result = (Double) denormalized; 
      isDouble = true; 
     } 
     else 
     { 
      denormalized = denormalized/10 ; 
     } 
     } 
     result = result/10 ; 
     scale-- ; 
    } 

    if (!isDouble) 
    { 
     return isNegativeResult ? Double.NegativeInfinity : Double.PositiveInfinity; 
    } 
    else 
    { 
     return result; 
    } 

    } 

    private const   int  DoubleMaxScale  = 308 ; 
    private static readonly BigInteger s_bnDoublePrecision = BigInteger.Pow(10 , DoubleMaxScale) ; 
    private static readonly BigInteger s_bnDoubleMaxValue = (BigInteger) Double.MaxValue; 
    private static readonly BigInteger s_bnDoubleMinValue = (BigInteger) Double.MinValue; 

    private static bool SafeCastToDouble(BigInteger value) 
    { 
    return s_bnDoubleMinValue <= value && value <= s_bnDoubleMaxValue; 
    } 

} 
+0

धन्यवाद। दुर्भाग्य से मैं बीटा में होने के बाद से उत्पादन कोड में बिगरेनल का उपयोग नहीं कर सकता। मंच और किताबें जवाब होना चाहिए। –

+1

@ राहेलखान: या आप बिगरेनल लाइब्रेरी से स्पष्ट रूपांतरण ऑपरेटर को निकाल सकते हैं और इसे आवश्यकतानुसार संशोधित कर सकते हैं। मुझे लगभग 15 मिनट लग गए (मेरा संपादित उत्तर देखें)। –

+0

धन्यवाद। विकल्पों को देखते हुए, यह शायद जाने का एकमात्र तरीका है। मुझे सही जवाब देने से पहले इसे पचाने और परीक्षण करने में कुछ समय लगेगा। –