खोज…


परिचय

फ़्लोटिंग-पॉइंट नंबर वे संख्याएँ होती हैं जिनमें भिन्नात्मक भाग होते हैं (आमतौर पर दशमलव बिंदु के साथ व्यक्त किए जाते हैं)। जावा में, फ्लोटिंग-पॉइंट संख्याओं के लिए दो आदिम प्रकार हैं जो float (4 बाइट्स का उपयोग करता है), और double (8 बाइट्स का उपयोग करता है)। यह प्रलेखन पृष्ठ उदाहरण संचालन के साथ विस्तार के लिए है जो जावा में फ्लोटिंग पॉइंट पर किया जा सकता है।

फ्लोटिंग पॉइंट वैल्यू की तुलना करना

संबंधपरक संचालकों का उपयोग करके फ्लोटिंग-पॉइंट वैल्यू ( float या double ) की तुलना करते समय आपको सावधान रहना चाहिए: == ; != < और इतने पर। ये ऑपरेटर फ्लोटिंग पॉइंट मानों के बाइनरी प्रतिनिधित्व के अनुसार परिणाम देते हैं। उदाहरण के लिए:

public class CompareTest {
    public static void main(String[] args) {
        double oneThird = 1.0 / 3.0;
        double one = oneThird * 3;
        System.out.println(one == 1.0);      // prints "false"
    }
}

गणना oneThird ने एक छोटी गोलाई त्रुटि पेश की है, और जब हम oneThird को 3 गुणा करते हैं, तो हमें एक परिणाम मिलता है जो 1.0 से थोड़ा भिन्न होता है।

जब हम गणना में double और float प्रयास करते हैं, तो निरूपण निरूपण की यह समस्या अधिक गंभीर है। उदाहरण के लिए:

public class CompareTest2 {
    public static void main(String[] args) {
        float floatVal = 0.1f;
        double doubleVal = 0.1;
        double doubleValCopy = floatVal;

        System.out.println(floatVal);      // 0.1
        System.out.println(doubleVal);     // 0.1
        System.out.println(doubleValCopy); // 0.10000000149011612
        
        System.out.println(floatVal == doubleVal); // false
        System.out.println(doubleVal == doubleValCopy); // false
    }
}

float और double प्रकारों के लिए जावा में उपयोग किए जाने वाले फ्लोटिंग पॉइंट अभ्यावेदनों में सीमित संख्या में सटीक अंक होते हैं। float प्रकार के लिए, सटीक 23 बाइनरी अंक या लगभग 8 दशमलव अंक हैं। double प्रकार के लिए, यह 52 बिट्स या लगभग 15 दशमलव अंक है। उसके शीर्ष पर, कुछ अंकगणितीय ऑपरेशन गोलाई त्रुटियों को पेश करेंगे। इसलिए, जब कोई प्रोग्राम फ्लोटिंग पॉइंट वैल्यू की तुलना करता है, तो यह तुलना के लिए स्वीकार्य डेल्टा को परिभाषित करने के लिए मानक अभ्यास करता है। यदि दो संख्याओं के बीच का अंतर डेल्टा से कम है, तो उन्हें बराबर माना जाता है। उदाहरण के लिए

if (Math.abs(v1 - v2) < delta)

डेल्टा तुलना उदाहरण:

public class DeltaCompareExample {

    private static boolean deltaCompare(double v1, double v2, double delta) {
        // return true iff the difference between v1 and v2 is less than delta
        return Math.abs(v1 - v2) < delta;
    }
    
    public static void main(String[] args) {
        double[] doubles = {1.0, 1.0001, 1.0000001, 1.000000001, 1.0000000000001};
        double[] deltas = {0.01, 0.00001, 0.0000001, 0.0000000001, 0};

        // loop through all of deltas initialized above
        for (int j = 0; j < deltas.length; j++) {
            double delta = deltas[j];
            System.out.println("delta: " + delta);

            // loop through all of the doubles initialized above
            for (int i = 0; i < doubles.length - 1; i++) {
                double d1 = doubles[i];
                double d2 = doubles[i + 1];
                boolean result = deltaCompare(d1, d2, delta);

                System.out.println("" + d1 + " == " + d2 + " ? " + result);
                
            }

            System.out.println();
        }
    }
}

परिणाम:

delta: 0.01
1.0 == 1.0001 ? true
1.0001 == 1.0000001 ? true
1.0000001 == 1.000000001 ? true
1.000000001 == 1.0000000000001 ? true

delta: 1.0E-5
1.0 == 1.0001 ? false
1.0001 == 1.0000001 ? false
1.0000001 == 1.000000001 ? true
1.000000001 == 1.0000000000001 ? true

delta: 1.0E-7
1.0 == 1.0001 ? false
1.0001 == 1.0000001 ? false
1.0000001 == 1.000000001 ? true
1.000000001 == 1.0000000000001 ? true

delta: 1.0E-10
1.0 == 1.0001 ? false
1.0001 == 1.0000001 ? false
1.0000001 == 1.000000001 ? false
1.000000001 == 1.0000000000001 ? false

delta: 0.0
1.0 == 1.0001 ? false
1.0001 == 1.0000001 ? false
1.0000001 == 1.000000001 ? false
1.000000001 == 1.0000000000001 ? false

इसके अलावा double और float की तुलना में आदिम प्रकार स्थिर इसी बॉक्सिंग प्रकार की compare विधि का उपयोग किया जा सकता है। उदाहरण के लिए:

double a = 1.0;
double b = 1.0001;

System.out.println(Double.compare(a, b));//-1
System.out.println(Double.compare(b, a));//1

अंत में, यह निर्धारित करना कि किसी तुलना के लिए डेल्टास सबसे उपयुक्त हैं, मुश्किल हो सकता है। आमतौर पर इस्तेमाल किया जाने वाला दृष्टिकोण डेल्टा मूल्यों को चुनना है जो हमारे अंतर्ज्ञान कहते हैं कि सही के बारे में हैं। हालाँकि, यदि आप इनपुट मानों के पैमाने और (सत्य) सटीकता को जानते हैं, और गणना की जाती है, तो परिणामों की सटीकता पर गणितीय रूप से ध्वनि सीमा के साथ आना संभव हो सकता है, और इसलिए डेल्टास के लिए। (गणित की एक औपचारिक शाखा है जिसे न्यूमेरिकल एनालिसिस के रूप में जाना जाता है जो कम्प्यूटेशनल वैज्ञानिकों को सिखाया जाता था जो एक तरह के विश्लेषण को कवर करता था।)

ओवरफ्लो और अंडरफ्लो

फ्लोट डेटा प्रकार

फ्लोट डेटा प्रकार एक एकल-सटीक 32-बिट IEEE 754 फ़्लोटिंग पॉइंट है।

Float ओवरफ्लो

अधिकतम संभव मूल्य 3.4028235e+38 , जब यह इस मूल्य से अधिक हो जाता है तो यह Infinity पैदा करता है

float f = 3.4e38f;
float result = f*2;        
System.out.println(result); //Infinity

Float अंडरफ्लो

न्यूनतम मूल्य 1.4e-45f है, जब इस मूल्य से नीचे जाता है तो यह 0.0 पैदा करता है

    float f = 1e-45f;
    float result = f/1000;
    System.out.println(result);

डबल डेटा प्रकार

डबल डेटा प्रकार एक डबल-सटीक 64-bit IEEE 754 फ़्लोटिंग पॉइंट है।

Double ओवरफ्लो

अधिकतम संभव मूल्य 1.7976931348623157e+308 , जब यह इस मूल्य से अधिक हो जाता है तो यह Infinity पैदा करता है

double d = 1e308;
double result=d*2;      
System.out.println(result); //Infinity

Double अंडरफ्लो

न्यूनतम मूल्य 4.9e-324 है, जब इस मूल्य से नीचे जाता है तो यह 0.0 पैदा करता है

    double d = 4.8e-323;
    double result = d/1000;
    System.out.println(result); //0.0

फ़्लोटिंग पॉइंट मानों को स्वरूपित करना

चल बिन्दु संख्या का उपयोग कर एक दशमलव संख्या के रूप में प्रारूपित किया जा सकता String.format साथ 'f' झंडा

    //Two digits in fracttional part are rounded
    String format1 = String.format("%.2f", 1.2399);
    System.out.println(format1); // "1.24"

    // three digits in fractional part are rounded 
    String format2 = String.format("%.3f", 1.2399);
    System.out.println(format2); // "1.240"
    
    //rounded to two digits, filled with zero 
    String format3 = String.format("%.2f", 1.2);
    System.out.println(format3); // returns "1.20"
    
    //rounder to two digits
    String format4 = String.format("%.2f", 3.19999);
    System.out.println(format4); // "3.20"

चल बिन्दु संख्या एक दशमलव संख्या का उपयोग कर के रूप में प्रारूपित किया जा सकता DecimalFormat

   // rounded with one digit fractional part 
    String format = new DecimalFormat("0.#").format(4.3200);
    System.out.println(format); // 4.3
    
   // rounded with two digit fractional part 
    String format = new DecimalFormat("0.##").format(1.2323000);
    System.out.println(format); //1.23

    // formatting floating numbers to decimal number
    double dv = 123456789;
    System.out.println(dv); // 1.23456789E8
    String format =  new DecimalFormat("0").format(dv);
    System.out.println(format); //123456789

IEEE विशिष्टता के लिए सख्त पालन

डिफ़ॉल्ट रूप से, float और double पर फ्लोटिंग पॉइंट ऑपरेशन IEEE 754 विनिर्देश के नियमों का कड़ाई से पालन नहीं करते हैं । एक अभिव्यक्ति को इन मूल्यों की सीमा तक कार्यान्वयन-विशिष्ट एक्सटेंशन का उपयोग करने की अनुमति है; अनिवार्य रूप से उन्हें आवश्यकता से अधिक सटीक होने की अनुमति देता है।

strictfp व्यवहार इस व्यवहार को अक्षम करता है। इसे एक वर्ग, इंटरफ़ेस या विधि पर लागू किया जाता है, और इसमें निहित हर चीज पर लागू होता है, जैसे कि कक्षाएं, इंटरफेस, तरीके, निर्माता, वैरिएबल इनिशियलाइज़र, आदि। strictfp साथ, फ़्लोटिंग-पॉइंट एक्सप्रेशन के मध्यवर्ती मान भीतर होने चाहिए। फ्लोट वैल्यू सेट या डबल वैल्यू सेट। यह इस तरह के भावों के परिणामों का कारण बनता है जो IEEE 754 विनिर्देश की भविष्यवाणी करते हैं।

सभी निरंतर भाव परोक्ष सख्त हैं, भले ही वे एक के भीतर नहीं हैं strictfp गुंजाइश।

इसलिए, कभी-कभी कुछ कोने के मामले की गणनाओं को कम सटीक बनाने के लिए strictfp प्रभाव का शुद्ध प्रभाव होता है, और यह फ्लोटिंग पॉइंट ऑपरेशंस को भी धीमा कर सकता है (जैसा कि सीपीयू अब यह सुनिश्चित करने के लिए अधिक काम कर रहा है कि कोई भी मूल अतिरिक्त परिशुद्धता परिणाम को प्रभावित नहीं करता है)। हालाँकि, यह सभी प्लेटफार्मों पर परिणाम समान होने का कारण भी बनता है। इसलिए यह वैज्ञानिक कार्यक्रमों जैसी चीजों में उपयोगी है, जहां प्रजनन क्षमता गति से अधिक महत्वपूर्ण है।

public class StrictFP { // No strictfp -> default lenient
    public strictfp float strict(float input) {
        return input * input / 3.4f; // Strictly adheres to the spec.
                                     // May be less accurate and may be slower.
    }

    public float lenient(float input) {
        return input * input / 3.4f; // Can sometimes be more accurate and faster,
                                     // but results may not be reproducable.
    }

    public static final strictfp class Ops { // strictfp affects all enclosed entities
        private StrictOps() {}

        public static div(double dividend, double divisor) { // implicitly strictfp
            return dividend / divisor;
        }
    }
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow