Java Language
जावा फ्लोटिंग पॉइंट ऑपरेशंस
खोज…
परिचय
फ़्लोटिंग-पॉइंट नंबर वे संख्याएँ होती हैं जिनमें भिन्नात्मक भाग होते हैं (आमतौर पर दशमलव बिंदु के साथ व्यक्त किए जाते हैं)। जावा में, फ्लोटिंग-पॉइंट संख्याओं के लिए दो आदिम प्रकार हैं जो 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;
}
}
}