2012-02-28 9 views
6

के लिए अंतिम स्थान (यूएलपी) में इकाई की गणना करें क्या .NET के पास दी गई डबल या फ्लोट के ULP की गणना करने के लिए अंतर्निहित विधि है?युगल

यदि नहीं, तो ऐसा करने का सबसे प्रभावी तरीका क्या है?

+0

खुश पढ़ने: http://stackoverflow.com/questions/1668183/find-min-max-of-a-float-double-that-has-the-same-internal-representation – vulkanino

उत्तर

4

ऐसा लगता है कि यह कार्य बहुत छोटा है; इस सवाल का vulkanino से जुड़े करने के लिए स्वीकार किए जाते हैं जवाब में स्यूडोकोड पर आधारित है:

double value = whatever; 
long bits = BitConverter.DoubleToInt64Bits(value); 
double nextValue = BitConverter.Int64BitsToDouble(bits + 1); 
double result = nextValue - value; 

तैरता के लिए, आप के बाद से BitConverter उन कार्यों नहीं है, SingleToInt32Bits और Int32BitsToSingle का अपना स्वयं का कार्यान्वयन प्रदान करने की आवश्यकता होगी।

This page फ़ंक्शन के जावा कार्यान्वयन में विशेष मामलों को दिखाता है; उनको संभालना भी काफी छोटा होना चाहिए।

1

फ़ूग उत्तर अच्छा है लेकिन नकारात्मक संख्याओं, max_double, अनंतता और NaN के साथ कमजोरियां हैं।

phoog_ULP (सकारात्मक x) -> एक सकारात्मक संख्या। अच्छा।
phoog_ULP (नकारात्मक x) -> एक ऋणात्मक संख्या। मैं सकारात्मक संख्या की उम्मीद करता हूं।
इसे ठीक करने के बजाय मैं सलाह देते हैं:

phoog_ULP (x = +/- Max_double 1.797 ... ई + 308) रिटर्न

long bits = BitConverter.DoubleToInt64Bits(value) & 0x7FFFFFFFFFFFFFFFL; 

नीचे हाशिये मामलों संकल्प आप ध्यान देना चाहिए की आवश्यकता है ... एक अनंत परिणाम। (+1.9 6 9 ... ई + 2 9 2) अपेक्षित। एक NaN में
phoog_ULP (x = +/- इन्फिनिटी) का परिणाम है। + अनंतता की उम्मीद है।
phoog_ULP (x = +/- NaN) अप्रत्याशित रूप से एक qNaN करने के लिए एक स्नान से बदल सकते हैं। कोई परिवर्तन नहीं की उम्मीद। यदि संकेत इस मामले में हो जाना चाहिए + एक बहस कर सकते या तो पर जिस तरह से।

इन हल करने के लिए, मैं सिर्फ पाशविक की एक छोटी श्रृंखला को देखने के() औचित्य के लिए "बिट" मूल्य पर इन, संभव समायोजित करने के लिए परीक्षण करता है, तो। उदाहरण:

double ulpc(double value) { 
    long long bits = BitConverter::DoubleToInt64Bits(value); 
    if ((bits & 0x7FF0000000000000L) == 0x7FF0000000000000L) { // if x is not finite 
    if (bits & 0x000FFFFFFFFFFFFFL) { // if x is a NaN 
     return value; // I did not force the sign bit here with NaNs. 
     } 
    return BitConverter.Int64BitsToDouble(0x7FF0000000000000L); // Positive Infinity; 
    } 
    bits &= 0x7FFFFFFFFFFFFFFFL; // make positive 
    if (bits == 0x7FEFFFFFFFFFFFFL) { // if x == max_double (notice the _E_) 
    return BitConverter.Int64BitsToDouble(bits) - BitConverter.Int64BitsToDouble(bits - 1); 
    } 
    double nextValue = BitConverter.Int64BitsToDouble(bits + 1); 
    double result = nextValue - value; 
}