दिलचस्प पोस्ट
सफलता के हैंडलर के बाहर $ एचपी वादा प्रतिक्रिया का उपयोग कैसे करें पृष्ठभूमि स्विफ्ट में ऑडियो कैसे खेलें? मैं किसी को जीआईटी रिपॉजिटरी कैसे ईमेल कर सकता हूं? कैसे PHP में एक datetime से AM / PM को प्राप्त करें जावा 7 (जेडीके 7) कचरा संग्रह और जी 1 पर प्रलेखन file_get_contents (): php_network_getaddresses: getaddrinfo विफल: नाम या सेवा ज्ञात नहीं है Google अजगर शैली गाइड नेविगेशन पट्टी प्रोग्रामिंग आईओएस जोड़ना पूर्णांक विभाजन के लिए सुरुचिपूर्ण पायथन कोड बिल्ड लक्ष्य के बाहर जीसीसी डीबग प्रतीक कैसे उत्पन्न करें? ईवेंट कैप्चरिंग jQuery CSS3 पर सीमा के साथ तरंग (या आकार?) जावा में, मैं कैसे जांचूं अगर कोई स्ट्रिंग में कोई सबस्ट्रिंग है (मामले की अनदेखी)? जावास्क्रिप्ट का इस्तेमाल करते हुए सर्वर से एक टेक्स्ट फाइल कैसे पढ़ सकती है? सी # में उच्च प्रदर्शन टीसीपी सर्वर

जावा में फ़्लोट्स के साथ प्रेसिजन त्रुटि

मैं सोच रहा हूं कि सटीक त्रुटियों को ठीक करने का सबसे अच्छा तरीका जावा में है जैसा कि आप निम्न उदाहरण में देख सकते हैं, सटीक त्रुटियां हैं:

class FloatTest { public static void main(String[] args) { Float number1 = 1.89f; for(int i = 11; i < 800; i*=2) { System.out.println("loop value: " + i); System.out.println(i*number1); System.out.println(""); } } } 

प्रदर्शित परिणाम है:

लूप वैल्यू: 11

20.789999

लूप वैल्यू: 22

41.579998

लूप वैल्यू: 44

83.159996

लूप वैल्यू: 88

१६६.३१,९९९

लूप वैल्यू: 176

३३२.६३,९९८

लूप वैल्यू: 352

६६५.२७,९९७

पाश मूल्य: 704

1330.5599

इसके अलावा, अगर कोई यह समझा सकता है कि यह केवल 11 से शुरू करने और हर बार मूल्य दोहरीकरण क्यों करता है मुझे लगता है कि अन्य सभी मूल्यों (या उनमें से बहुत कम) सही परिणाम प्रदर्शित करते हैं

इस तरह की समस्याएं मुझे अतीत में सिरदर्द बना देती हैं और आमतौर पर मैं नंबर फ़ॉर्मेटर्स का उपयोग करता हूं या उन्हें स्ट्रिंग में डाल देता हूं।

संपादित करें: जैसा कि लोगों ने उल्लेख किया है, मैं एक डबल उपयोग कर सकता हूं, लेकिन कोशिश करने के बाद, ऐसा लगता है कि 1.89 दो बार के रूप में 792 अभी भी एक त्रुटि (उत्पादन 1496.8799999999999) है।

मुझे लगता है कि मैं बिगडीकल जैसी अन्य समाधानों की कोशिश करूंगा

Solutions Collecting From Web of "जावा में फ़्लोट्स के साथ प्रेसिजन त्रुटि"

यदि आप वास्तव में परिशुद्धता के बारे में परवाह करते हैं, तो आपको बिगडीकल का उपयोग करना चाहिए

http://download.oracle.com/javase/1,5.0/docs/api/java/math/BigDecimal.html

समस्या जावा के साथ नहीं बल्कि अच्छे मानक फ्लोट के साथ है ( http://en.wikipedia.org/wiki/IEEE_floating-point_standard )

आप या तो यह कर सकते हैं:

  • डबल का उपयोग करें और थोड़ा अधिक सटीक है (लेकिन निश्चित रूप से बिल्कुल सही नहीं है, इसमें सीमित परिशुद्धता भी है)

  • एक मनमाना-सटीक-पुस्तकालय का उपयोग करें

  • संख्यात्मक रूप से स्थिर एल्गोरिदम का उपयोग करें और ट्रंकेट / गोल अंक जो आप सुनिश्चित नहीं हैं कि वे सही हैं (आप परिचालन की संख्यात्मक सटीक गणना कर सकते हैं)

जब आप एक डबल ऑपरेशन के परिणाम को प्रिंट करते हैं तो आपको उपयुक्त गोलाई का उपयोग करने की आवश्यकता होती है।

 System.out.printf("%.2f%n", 1.89 * 792); 

प्रिंट

 1496.88 

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

 double d = 1.89 * 792; d = Math.round(d * 100) / 100.0; System.out.println(d); 

प्रिंट

 1496.88 

हालांकि यदि आप नीचे देखें, यह अपेक्षित रूप से छापता है, क्योंकि निहित घूर्णन की एक छोटी राशि है


यह कुछ भी नहीं है (double) 1.89 बिल्कुल नहीं है 1.89 यह एक करीबी सन्निकटन है

नई बिगडीक्यैमल (डबल) किसी भी निहित गोलाई के बिना डबल के सटीक मान को परिवर्तित करता है। यह डबल के सटीक मूल्य को खोजने में उपयोगी हो सकता है

 System.out.println(new BigDecimal(1.89)); System.out.println(new BigDecimal(1496.88)); 

प्रिंट

 1.8899999999999999023003738329862244427204132080078125 1496.8800000000001091393642127513885498046875 

आप फ्लोट के बजाय डबल्स का उपयोग कर सकते हैं

अगर आपको वास्तव में मनमाने ढंग से परिशुद्धता की आवश्यकता है, तो BigDecimal का उपयोग करें

Float पहले आदिम float लिए आवरण वर्ग है

और डबल्स में अधिक परिशुद्धता है

लेकिन अगर आप केवल दूसरे अंकों (उदाहरण के लिए मौद्रिक प्रयोजनों के लिए) की गणना करना चाहते हैं, तो एक पूर्णांक का उपयोग करें (जैसा कि आप इकाई के रूप में सेंट का उपयोग कर रहे हैं) और जब आप गुणा / विभाजन कर रहे हैं तो कुछ स्केलिंग तर्क जोड़ सकते हैं

या यदि आपको मनमाने ढंग से परिशुद्धता की आवश्यकता है तो BigDecimal उपयोग करें

आपके अधिकांश प्रश्न बहुत अच्छी तरह से कवर किए गए हैं, हालांकि आप अभी भी [floating-point] टैग विकी को पढ़ने से लाभान्वित हो सकते हैं ताकि समझ सकें कि अन्य जवाब क्यों काम करते हैं।

हालांकि, किसी ने भी "यह केवल 11 से शुरू करने और हर बार मूल्य दोहरीकरण क्यों करता है" कहा है, इसलिए यहां इसका उत्तर दिया गया है:

 for(int i = 11; i < 800; i*=2) ╚═══╤════╝ ╚╤═╝ │ └───── "double the value every time" │ └───── "start at 11" 

यदि सटीक महत्वपूर्ण है, तो आपको यह सुनिश्चित करने के लिए बिगडीकल का उपयोग करना चाहिए कि आवश्यक सटीकता बनी हुई है। जब आप गणना को इन्स्तांत करते हैं, तो युगल के बजाय मूल्यों को इन्स्तांत करने के लिए तार का उपयोग करना याद रखें।