फ्लोटिंग पॉइंट के नुकसान से बचने के लिए प्रोग्रामिंग लैंग्वेज का क्या किया जा सकता है?


28

फ्लोटिंग पॉइंट अंकगणित और इसकी लघु-कॉमिंग की गलतफहमी प्रोग्रामिंग में आश्चर्य और भ्रम का एक प्रमुख कारण है (स्टैक ओवरफ्लो पर प्रश्नों की संख्या पर विचार करें "सही ढंग से जोड़ना नहीं है"। कई प्रोग्रामर्स को ध्यान में रखते हुए, इसके निहितार्थ को समझना अभी बाकी है, इसमें कई सूक्ष्म बग (विशेषकर वित्तीय सॉफ्टवेयर में) को पेश करने की क्षमता है। क्या प्रोग्रामिंग भाषाओं, जबकि अभी भी अपनी गति की पेशकश जब सटीकता उन है कि के लिए महत्वपूर्ण नहीं है, उन है कि अवधारणाओं से परिचित नहीं हैं के लिए अपने नुकसान से बचने के लिए क्या कर सकते हैं करना अवधारणाओं को समझने?


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

4
यह "न्यूमेरिकल एनालिसिस" है। सटीक हानि को कम करने का तरीका जानें - उर्फ ​​फ्लोटिंग पॉइंट नुकसान।

फ्लोटिंग पॉइंट इश्यू का एक अच्छा उदाहरण: stackoverflow.com/questions/10303762/0-0-0-0-0-0
ऑस्टिन हेनले

जवाबों:


47

आप कहते हैं "विशेष रूप से वित्तीय सॉफ्टवेयर के लिए", जो मेरे पालतू जानवरों में से एक को लाता है: पैसा एक फ्लोट नहीं है, यह एक इंट है

यकीन है, यह एक नाव की तरह लग रहा है। इसमें एक दशमलव बिंदु है। लेकिन ऐसा सिर्फ इसलिए है क्योंकि आप उन इकाइयों के लिए उपयोग किए जाते हैं जो समस्या को भ्रमित करते हैं। पैसा हमेशा पूर्णांक मात्रा में आता है। अमेरिका में, यह सेंट है। (कुछ संदर्भों में मुझे लगता है कि यह मिलें हो सकती हैं , लेकिन अभी के लिए इसे अनदेखा करें।)

इसलिए जब आप $ 1.23 कहते हैं, तो यह वास्तव में 123 सेंट है। हमेशा, हमेशा, हमेशा उन शब्दों में अपना गणित करो, और तुम ठीक हो जाओगे। अधिक जानकारी के लिए देखें:

सीधे सवाल का जवाब देते हुए, प्रोग्रामिंग भाषाओं में एक उचित आदिम के रूप में केवल एक पैसा प्रकार शामिल होना चाहिए।

अद्यतन करें

ठीक है, मुझे केवल तीन बार के बजाय केवल "हमेशा" दो बार कहना चाहिए था। पैसा वास्तव में हमेशा एक इंट होता है; जो लोग सोचते हैं कि आपका स्वागत है मुझे 0.3 सेंट भेजने और अपने बैंक स्टेटमेंट पर मुझे परिणाम दिखाने का प्रयास करें। लेकिन जब टिप्पणीकार इशारा करते हैं, तब दुर्लभ अपवाद होते हैं जब आपको पैसे की तरह संख्याओं पर फ्लोटिंग पॉइंट गणित करने की आवश्यकता होती है। जैसे, कुछ प्रकार की कीमतें या ब्याज की गणना। फिर भी, उन लोगों को अपवाद की तरह माना जाना चाहिए। पैसा अंदर आता है और पूर्णांक मात्रा के रूप में निकलता है, इसलिए आपका सिस्टम जितना करीब होगा, वह उतना ही पवित्र होगा।


20
@JoelFan: आप एक मंच विशिष्ट कार्यान्वयन के लिए एक अवधारणा को गलत कर रहे हैं।
whatsisname

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

24
काल्पनिक -1, क्योंकि मेरे पास एक डाउनवोट के लिए प्रतिनिधि की कमी है :) ... यह आपके बटुए में जो कुछ भी है उसके लिए सही हो सकता है, लेकिन बहुत सारी लेखांकन स्थितियां हैं जहां आप एक प्रतिशत के दसवें, या छोटे अंशों से अच्छी तरह से निपट सकते हैं। Decimalइस से निपटने के लिए केवल समझदार प्रणाली है, और अपनी टिप्पणी "उपेक्षा है कि अब के लिए" है प्रोग्रामर के लिए कयामत का अग्रदूत हर जगह: पी
detly

9
@ स्क्विन क्लाइन: गणना में भिन्नात्मक सेंट हैं, लेकिन उन्हें कैसे संभाला जाए, इस पर विचार-विमर्श किया जाता है। वित्तीय गणना के लिए लक्ष्य गणितीय शुद्धता नहीं है, लेकिन सटीक वही परिणाम प्राप्त करना है जो एक कैलकुलेटर के साथ एक बैंकर होगा।
डेविड थॉर्नले

6
"पूर्णांक" शब्द को "तर्कसंगत" के स्थान पर रखने से सब कुछ सही होगा -
एमिलियो गरवाग्लिया

15

दशमलव प्रकार के लिए समर्थन प्रदान करने से कई मामलों में मदद मिलती है। कई भाषाओं में दशमलव प्रकार होता है, लेकिन उनका उपयोग किया जाता है।

वास्तविक संख्याओं के प्रतिनिधित्व के साथ काम करते समय होने वाले सन्निकटन को समझना महत्वपूर्ण है। दशमलव और फ़्लोटिंग पॉइंट दोनों प्रकारों 9 * (1/9) != 1का उपयोग करना एक सही कथन है। जब एक ऑप्टिमाइज़र गणना का अनुकूलन कर सकता है ताकि यह सही हो।

एक सन्निकट ऑपरेटर प्रदान करने से मदद मिलेगी। हालांकि, ऐसी तुलनाएं समस्याग्रस्त हैं। ध्यान दें कि .9999 ट्रिलियन डॉलर लगभग 1 ट्रिलियन डॉलर के बराबर है। क्या आप मेरे बैंक खाते में अंतर जमा कर सकते हैं?


2
0.9999...खरब डॉलर वास्तव में 1 ट्रिलियन डॉलर के बराबर है।
मेरा सही ओपिनियन

5
@ जज: हां, लेकिन मैंने रजिस्टरों वाले किसी भी कंप्यूटर का सामना नहीं किया है जो पकड़ में आएगा 0.99999...। वे सभी किसी न किसी मोड़ पर एक असमानता के कारण काटते हैं। 0.9999इंजीनियरिंग के लिए पर्याप्त है। वित्तीय उद्देश्यों के लिए यह नहीं है।
बिलथोर

2
लेकिन किस तरह की प्रणाली ने डॉलर के बजाय अरबों डॉलर को आधार इकाई के रूप में इस्तेमाल किया?
ब्रैड

@ ब्रैड गणना करें (1 ट्रिलियन / 3) * 3 अपने कैलकुलेटर पर। आपको क्या मूल्य मिलता है?
BillThor 13

8

हमें बताया गया था कि जब मैं विश्वविद्यालय गया था, तो कंप्यूटर विज्ञान में प्रथम वर्ष (सोम्पोमोर) व्याख्यान में क्या करना था, (यह पाठ्यक्रम अधिकांश विज्ञान पाठ्यक्रमों के लिए भी एक पूर्व-आवश्यकता थी)

मुझे व्याख्याता ने याद करते हुए कहा "फ्लोटिंग पॉइंट नंबर सन्निकटन हैं। पैसे के लिए पूर्णांक प्रकारों का उपयोग करें। सटीक गणना के लिए BCD नंबरों के साथ FORTRAN या अन्य भाषा का उपयोग करें।" (और फिर उन्होंने सन्निकटन को इंगित किया, बाइनरी फ्लोटिंग पॉइंट में सटीक रूप से प्रतिनिधित्व करने के लिए असंभव 0.2 के उस क्लासिक उदाहरण का उपयोग करके)। प्रयोगशाला अभ्यास में यह उस सप्ताह भी बदल गया।

एक ही व्याख्यान: "यदि आपको फ़्लोटिंग पॉइंट से अधिक सटीकता प्राप्त करनी चाहिए, तो अपनी शर्तों को क्रमबद्ध करें। छोटी संख्याओं को एक साथ जोड़ें, बड़ी संख्याओं के लिए नहीं।" वह मेरे दिमाग में अटक गया।

कुछ साल पहले मेरे पास कुछ गोलाकार ज्यामिति थी जो बहुत सटीक होने की आवश्यकता थी, और अभी भी तेज है। पीसी पर 80 बिट डबल इसे काट नहीं रहा था, इसलिए मैंने प्रोग्राम में कुछ प्रकार जोड़े जो कि कम्यूटेटिव ऑपरेशन करने से पहले शब्दों को क्रमबद्ध करता था। समस्या सुलझ गयी।

इससे पहले कि आप गिटार की गुणवत्ता के बारे में शिकायत करें, खेलना सीखें।

मेरे पास चार साल पहले एक सहकर्मी था जो जेपीएल के लिए काम करता था। उन्होंने अविश्वास व्यक्त किया कि हमने कुछ चीजों के लिए फोरट्रान का उपयोग किया है। (हमें ऑफ़लाइन गणना के लिए सुपर सटीक संख्यात्मक सिमुलेशन की आवश्यकता थी।) "हमने सी ++ के साथ फोरट्रान को बदल दिया" उसने गर्व से कहा। मुझे आश्चर्य हुआ कि उन्होंने एक ग्रह को क्यों याद किया।


2
सही काम के लिए सही उपकरण। हालांकि मैं वास्तव में फोरट्रान का उपयोग नहीं करता हूं। शुक्र है कि न तो मैं काम पर हमारे वित्तीय प्रणालियों पर काम करते हैं।
जेम्स खुरेई

"यदि आपको फ़्लोटिंग पॉइंट से अधिक सटीकता प्राप्त करनी है, तो अपनी शर्तों को क्रमबद्ध करें। छोटी संख्याओं को एक साथ जोड़ें, बड़ी संख्याओं के लिए नहीं।" इस पर कोई नमूना?
mamcx

@mamcx एक दशमलव फ्लोटिंग पॉइंट संख्या की कल्पना करें, जिसमें केवल एक अंक का अंकन हो। अभिकलन 1.0 + 0.1 + ... + 0.1(10 बार दोहराया) के 1.0रूप में हर मध्यवर्ती परिणाम गोल हो जाता है। यह इसका उल्टा कर रही है, आप के मध्यवर्ती परिणाम प्राप्त 0.2, 0.3, ..., 1.0और अंत में 2.0। यह एक चरम उदाहरण है, लेकिन यथार्थवादी फ्लोटिंग पॉइंट संख्याओं के साथ, इसी तरह की समस्याएं होती हैं। आधार विचार यह है कि आकार में समान संख्याओं को जोड़ने से सबसे छोटी त्रुटि होती है। छोटी संख्या के साथ शुरू करें क्योंकि उनका योग बड़ा है और इसलिए बड़े लोगों के लिए बेहतर अनुकूल है।
मातरिनस

फ़ोर्ट्रान और C ++ में फ़्लोटिंग पॉइंट सामान हालांकि ज्यादातर समान होने जा रहा है। दोनों सटीक और ऑफ़लाइन हैं, और मुझे पूरा यकीन है कि फोरट्रान का कोई मूल बीसीडी रियल नहीं है ...
मार्क

8

चेतावनी: फ्लोटिंग-पॉइंट टाइप System.Double प्रत्यक्ष समानता परीक्षण के लिए सटीक का अभाव है।

double x = CalculateX();
if (x == 0.1)
{
    // ............
}

मुझे विश्वास नहीं है कि भाषा के स्तर पर कुछ भी किया जा सकता है या किया जाना चाहिए।


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

1
@ कार्ल - व्यक्तिगत रूप से मैंने इसे नहीं देखा है या इसकी आवश्यकता नहीं है लेकिन मुझे लगता है कि यह समर्पित लेकिन हरे डेवलपर्स के लिए उपयोगी हो सकता है।
चोसपंडियन

1
बाइनरी फ़्लोटिंग पॉइंट प्रकार Decimalसमानता परीक्षण से पहले की तुलना में बेहतर या अधिक गुणात्मक नहीं हैं । के बीच का अंतर 1.0m/7.0m*7.0mऔर 1.0mपरिमाण के अंतर के कई अंतर हो सकते हैं 1.0/7.0*7.0, लेकिन यह शून्य नहीं है।
Supercat

1
@ पैट्रिक - मुझे यकीन नहीं है कि आप क्या कर रहे हैं। एक मामले के लिए कुछ सच होने और सभी मामलों के लिए सही होने के बीच एक बड़ा अंतर है।
ChaosPandion

1
@ChaosPandion इस पोस्ट में उदाहरण के साथ समस्या समानता-तुलना नहीं है, यह फ्लोटिंग-पॉइंट शाब्दिक है। 1.0 / 10 के सटीक मान के साथ कोई फ्लोट नहीं है। मंटिसा के भीतर पूर्णांक संख्या फिटिंग के साथ कंप्यूटिंग करते समय फ्लोटिंग पॉइंट मैथ्स 100% सटीक परिणाम देता है।
पैट्रिक

7

डिफ़ॉल्ट रूप से, भाषाओं को गैर-पूर्णांक संख्याओं के लिए मनमाना-सटीक परिमेय का उपयोग करना चाहिए।

जिन लोगों को अनुकूलन करने की आवश्यकता होती है, वे हमेशा तैरने के लिए कह सकते हैं। सी और अन्य सिस्टम प्रोग्रामिंग भाषाओं में डिफ़ॉल्ट रूप से समझदारी के रूप में उनका उपयोग करना, लेकिन आज लोकप्रिय अधिकांश भाषाओं में नहीं।


1
आप तर्कहीन संख्याओं से कैसे निपटते हैं?
dsimcha

3
आप इसे उसी तरह से करते हैं जैसे तैरते हैं: सन्निकटन।
19-13 को वाको

1
मुझे लगता है मुझे लगता है कि यह बहुत समझ में आता है, ज्यादातर लोगों को जिन्हें सटीक संख्या की आवश्यकता होती है उन्हें तर्कशक्ति की आवश्यकता नहीं होती है (विज्ञान और इंजीनियरिंग तर्कहीन का उपयोग कर सकते हैं लेकिन आप फिर से लगभग वास्तविक दायरे में हैं, या आप कुछ महत्वपूर्ण शुद्ध गणित कर रहे हैं)
जे.के.

1
मनमाने ढंग से सटीक युक्तियों के साथ संगणना अक्सर एक हार्डवेयर-समर्थित के साथ संगणना की तुलना में परिमाण धीमे (संभवतः परिमाण धीमे के आदेश) के आदेश होंगे double। यदि किसी गणना को प्रति मिलियन भाग के लिए सटीक होना चाहिए, तो एक माइक्रोसेकंड कंप्यूटिंग के लिए इसे कुछ बिलियन प्रति बिलियन के भीतर खर्च करना बेहतर होता है, दूसरी कंप्यूटिंग को बिल्कुल ठीक खर्च करने की तुलना में।
15 अक्टूबर को सुपरकैट

5
@ सुपरकैट: आप जो सुझाव दे रहे हैं वह समय से पहले के अनुकूलन का सिर्फ एक पोस्टर-बच्चा है। वर्तमान स्थिति यह है कि बड़ी संख्या में प्रोग्रामर को तेज गणित के लिए किसी की कोई आवश्यकता नहीं है, और फिर फ्लोटिंग-पॉइंट (गलत) व्यवहार को समझने के लिए कड़ी मेहनत से काट लिया जाता है, ताकि अपेक्षाकृत कम संख्या में प्रोग्रामर जिन्हें फास्ट गणित की आवश्यकता होती है, बिना हो एक अतिरिक्त चरित्र टाइप करने के लिए। सत्तर के दशक में यह समझ में आया, अब यह सिर्फ बकवास है। डिफ़ॉल्ट सुरक्षित होना चाहिए। जिन्हें उपवास की जरूरत है, उन्हें इसके लिए पूछना चाहिए।
19-13 को वाको

4

फ़्लोटिंग पॉइंट नंबर वाली दो सबसे बड़ी समस्याएं हैं:

  • गणनाओं पर लागू असंगत इकाइयाँ (ध्यान दें कि यह पूर्णांक अंकगणित को भी उसी तरह प्रभावित करती है)
  • यह समझने में विफलता कि एफपी नंबर एक अनुमान है और गोलाई के साथ समझदारी से कैसे निपटना है।

पहले प्रकार की विफलता को केवल एक समग्र प्रकार प्रदान करके सुधारा जा सकता है जिसमें मूल्य और इकाई जानकारी शामिल होती है। उदाहरण के लिए, lengthया areaइकाई (मीटर या वर्ग मीटर या पैर और वर्ग फुट) को शामिल करने वाला मान। अन्यथा आपको माप की एक इकाई के साथ हमेशा काम करने के बारे में मेहनती होना चाहिए और जब हम मानव के साथ उत्तर साझा करते हैं तो केवल दूसरे में परिवर्तित होते हैं।

दूसरे प्रकार की विफलता एक वैचारिक विफलता है। असफलताएं खुद को प्रकट करती हैं जब लोग उनके बारे में निरपेक्ष संख्या के रूप में सोचते हैं । यह समानता संचालन, संचयी गोलाई त्रुटियों आदि को प्रभावित करता है। उदाहरण के लिए, यह सही हो सकता है कि एक प्रणाली के लिए दो माप त्रुटि के एक निश्चित मार्जिन के बराबर हैं। Ie .999 और 1.001 लगभग 1.0 के समान हैं जब आप उन अंतरों के बारे में परवाह नहीं करते हैं जो +/1.1 से छोटे हैं। हालांकि, सभी सिस्टम उस उदार नहीं हैं।

अगर किसी भी भाषा स्तर की सुविधा की आवश्यकता है, तो मैं इसे समानता परिशुद्धता कहूंगा । NUnit, JUnit, और इसी तरह से निर्मित परीक्षण रूपरेखा में आप उस शुद्धता को नियंत्रित कर सकते हैं जिसे सही माना जाता है। उदाहरण के लिए:

Assert.That(.999, Is.EqualTo(1.001).Within(10).Percent);
// -- or --
Assert.That(.999, Is.EqualTo(1.001).Within(.1));

यदि, उदाहरण के लिए, सी # या जावा को एक सटीक ऑपरेटर शामिल करने के लिए बदल दिया गया था, तो यह कुछ इस तरह दिख सकता है:

if(.999 == 1.001 within .1) { /* do something */ }

हालांकि, यदि आप उस तरह की सुविधा देते हैं, तो आपको उस मामले पर भी विचार करना होगा जहां समानता अच्छी है अगर +/- पक्ष समान नहीं हैं। उदाहरण के लिए, + 1 / -10 दो संख्याओं के समतुल्य समझेगा यदि उनमें से एक संख्या 1 से अधिक थी, या पहली संख्या से 10 कम थी। इस मामले को संभालने के लिए, आपको एक rangeकीवर्ड जोड़ना होगा :

if(.999 == 1.001 within range(.001, -.1)) { /* do something */ }

2
मैं ऑर्डर बंद कर दूंगा। वैचारिक समस्या व्याप्त है। तुलनात्मक रूप से इकाइयों का रूपांतरण मुद्दा अपेक्षाकृत मामूली है।
एस.लॉट

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

यह बहुत आसानी से एक पुस्तकालय में भी किया जा सकता है।
माइकल के

1
@ dan04: मैं "एक प्रतिशत के भीतर सटीक सभी गणनाओं" या इस तरह के रूप में अधिक सोच रहा था। मैंने टार-पिट को देखा है जो माप से निपटने की इकाई है और मैं अच्छी तरह से दूर रह रहा हूं।
TMN

1
लगभग 25 साल पहले, मैंने एक संख्यात्मक पैकेज देखा, जिसमें एक प्रकार का फ्लोटिंग-पॉइंट नंबरों की एक जोड़ी थी, जो एक मात्रा के लिए अधिकतम और न्यूनतम संभव मानों का प्रतिनिधित्व करता था। जैसे-जैसे संख्याएँ गणना से गुज़रती जाती हैं, अधिकतम और न्यूनतम के बीच का अंतर बढ़ता जाता है। प्रभावी रूप से, यह जानने का एक साधन था कि गणना मूल्य में कितनी वास्तविक परिशुद्धता मौजूद थी।
Supercat

3

प्रोग्रामिंग लैंग्वेज क्या कर सकती हैं? अगर उस सवाल का कोई जवाब नहीं है, तो यह न जानें, क्योंकि कंपाइलर / दुभाषिया प्रोग्रामर की ओर से कुछ भी करता है, जिससे उसका जीवन आसान हो जाता है, आमतौर पर प्रदर्शन, स्पष्टता और पठनीयता के खिलाफ काम करता है। मुझे लगता है कि दोनों सी ++ तरीका (केवल आपकी आवश्यकता के लिए भुगतान करें) और पर्ल तरीका (कम से कम आश्चर्य का सिद्धांत) दोनों वैध हैं, लेकिन यह आवेदन पर निर्भर करता है।

प्रोग्रामर को अभी भी भाषा के साथ काम करने और यह समझने की आवश्यकता है कि यह फ्लोटिंग पॉइंट्स को कैसे संभालता है, क्योंकि यदि वे नहीं करते हैं, तो वे धारणाएं बनाएंगे, और एक दिन सताए गए व्यवहार उनकी मान्यताओं के साथ मेल नहीं खाएंगे।

मेरा प्रोग्रामर को क्या पता होना चाहिए:

  • सिस्टम पर और भाषा में कौन से फ्लोटिंग-पॉइंट प्रकार उपलब्ध हैं
  • किस प्रकार की आवश्यकता है
  • कोड में किस प्रकार के इरादों को व्यक्त करना है
  • शुद्धता को बनाए रखते हुए स्पष्टता और दक्षता को संतुलित करने के लिए किसी भी स्वचालित प्रकार के प्रचार का सही ढंग से लाभ कैसे उठाएं

3

[अस्थायी बिंदु] नुकसान से बचने के लिए प्रोग्रामिंग भाषाएं क्या कर सकती हैं ...?

समझदार चूक का उपयोग करें, उदाहरण के लिए decmials के लिए अंतर्निहित समर्थन।

ग्रूवी यह काफी अच्छी तरह से करता है, हालांकि थोड़े प्रयास के साथ आप अभी भी फ्लोटिंग पॉइंट इंप्रेशन शुरू करने के लिए कोड लिख सकते हैं।


3

मैं मानता हूं कि भाषा के स्तर पर कुछ नहीं करना है। प्रोग्रामर को समझना चाहिए कि कंप्यूटर असतत और सीमित हैं, और उनमें से कई गणितीय अवधारणाओं का केवल अनुमान है।

कभी भी फ्लोटिंग पॉइंट को ध्यान में न रखें। किसी को यह समझना होगा कि आधे पैटर्न का उपयोग नकारात्मक संख्याओं के लिए किया जाता है और यह 2 ^ 64 पूर्णांक अंकगणित के साथ विशिष्ट समस्याओं से बचने के लिए वास्तव में काफी छोटा है।


असहमत, अधिकांश भाषा वर्तमान में बाइनरी फ़्लोटिंग पॉइंट प्रकारों के लिए बहुत अधिक समर्थन देती है (क्यों == यहां तक ​​कि फ़्लोट्स के लिए परिभाषित किया गया है?) और तर्कसंगत या दशमलव के लिए पर्याप्त समर्थन नहीं
jk।

@jk: भले ही किसी भी संगणना के परिणाम की गारंटी किसी अन्य संगणना के परिणाम के बराबर नहीं होगी, फिर भी समानता की तुलना उस मामले के लिए उपयोगी होगी, जहाँ समान मूल्य दो चर को सौंपा जाता है (हालाँकि आमतौर पर लागू होने वाले समानता नियम शायद ही लागू होते हैं। बहुत ढीली, चूंकि x== का yअर्थ यह नहीं है कि किसी संगणना का प्रदर्शन xउसी परिणाम का परिणाम देगा जैसा कि गणना पर होता है y)।
15 अक्टूबर को सुपरकैट

@supercat आपको अभी भी तुलना की आवश्यकता है, लेकिन मुझे हर अस्थायी बिंदु की तुलना के लिए एक सहिष्णुता निर्दिष्ट करने के लिए भाषा की आवश्यकता है, फिर भी मैं सहिष्णुता = 0 चुनकर समानता पर वापस आ सकता हूं, लेकिन मुझे कम से कम यह करने के लिए मजबूर होना चाहिए पसंद
jk

3

एक बात भाषाएं कर सकती हैं - NAN मूल्यों की सीधी तुलना के अलावा अन्य फ्लोटिंग पॉइंट प्रकारों से समानता की तुलना को हटा दें।

समानता परीक्षण केवल तभी मौजूद होगा जब फ़ंक्शन कॉल में दो मान और एक डेल्टा लिया गया हो, या C # जैसी भाषाओं के लिए जो कि प्रकारों को एक समान मान रखने की अनुमति देता है, जो कि अन्य मान और डेल्टा लेता है।


3

मुझे यह अजीब लगता है कि किसी ने लिस्प परिवार के तर्कसंगत संख्या चाल को इंगित नहीं किया है।

गंभीरता से, sbcl खोलें, और यह करें: (+ 1 3)और आपको 4 मिलता है। यदि आप करते *( 3 2)हैं तो आपको मिलता है 6. अब प्रयास करें (/ 5 3)और आपको 5/3, या 5 तिहाई मिलता है।

यह कुछ स्थितियों में कुछ मदद करनी चाहिए, है ना?


मुझे आश्चर्य है, अगर यह जानना संभव है कि क्या परिणाम को 1/3 के रूप में दर्शाया जाना चाहिए या एक सटीक दशमलव हो सकता है?
mamcx

अच्छा सुझाव
पीटर पोर्फी

3

एक बात मैं देखना चाहेंगे एक मान्यता है कि हो सकता है doubleके लिए float, एक को चौड़ा रूपांतरण के रूप में माना जाना चाहिए, जबकि floatकरने के लिए doubleसीमित करने है (*)। यह सहज ज्ञान युक्त लग सकता है, लेकिन विचार करें कि वास्तव में किस प्रकार का अर्थ है:

  • 0.1f का अर्थ है "13,421,773.5 / 134,217,728, प्लस या माइनस 1 / 268,435,456 या तो"।
  • 0.1 का वास्तव में मतलब है 3,602,879,701,896,397 / 36,028,797,018,963,968, प्लस या माइनस 1 / 72,057,594,037,927,936 या तो "

यदि किसी के पास double"एक-दसवां" मात्रा का सबसे अच्छा प्रतिनिधित्व है और इसे धर्मान्तरित करता है float, तो परिणाम "13,421,773.5 / 134,217,728, प्लस या माइनस 1 / 268,435,456 या" होगा, जो मूल्य का सही विवरण है।

इसके विपरीत, यदि किसी के पास float"एक-दसवें" मात्रा का सबसे अच्छा प्रतिनिधित्व है और इसे धर्मान्तरित करता है double, तो परिणाम "13,421,773.5 / 134,217,728, प्लस या माइनस 1 / 72,057,5,5,037,927,936 या तो" होगा - निहित सटीकता का एक स्तर जो 53 मिलियन से अधिक के कारक से गलत है।

हालाँकि IEEE-744 मानक के लिए यह आवश्यक है कि फ्लोटिंग-पॉइंट मैथ्स का प्रदर्शन किया जाए, हालाँकि हर फ़्लोटिंग-पॉइंट संख्या इसकी संख्या के केंद्र में सटीक संख्यात्मक मात्रा का प्रतिनिधित्व करती है, लेकिन इसका मतलब यह नहीं निकाला जाना चाहिए कि फ्लोटिंग-पॉइंट वैल्यू वास्तव में उन सटीक का प्रतिनिधित्व करते हैं संख्यात्मक मात्रा। इसके बजाय, यह मान लिया जाना चाहिए कि मानों को उनकी सीमा के केंद्र में तीन तथ्यों से उपजा है: (1) गणना का प्रदर्शन किया जाना चाहिए जैसे कि ऑपरेंड के कुछ विशेष सटीक मान हैं; (२) असंगत या अविवादित लोगों की तुलना में सुसंगत और प्रलेखित मान्यताएँ अधिक सहायक होती हैं; (३) यदि कोई एक सुसंगत धारणा बनाने जा रहा है, तो कोई अन्य सुसंगत धारणा यह मानने से बेहतर है कि कोई मात्रा उसकी श्रेणी के केंद्र का प्रतिनिधित्व करती है।

संयोग से, मुझे कुछ 25 साल या उससे पहले याद है, कोई व्यक्ति सी के लिए संख्यात्मक पैकेज के साथ आया था जिसमें "रेंज प्रकार" का उपयोग किया गया था, प्रत्येक में 128-बिट फ़्लोट की एक जोड़ी शामिल थी; सभी गणनाएं इस तरह से की जाएंगी कि प्रत्येक परिणाम के लिए न्यूनतम और अधिकतम संभव मूल्य की गणना की जा सके। यदि कोई एक बड़ी लंबी पुनरावृत्ति गणना करता है और [12.53401391134 12.53902812673] के मान के साथ आता है, तो एक को विश्वास हो सकता है कि जबकि परिशुद्धता के कई अंक राउंडिंग त्रुटियों में खो गए थे, परिणाम अभी भी यथोचित रूप से 12.54 (और यह wasn ') के रूप में व्यक्त किया गया है t वास्तव में १२.९ या ५३.२)। मुझे आश्चर्य है कि मैंने किसी भी मुख्यधारा की भाषाओं में इस प्रकार के लिए कोई समर्थन नहीं देखा है, खासकर जब से वे गणित इकाइयों के साथ एक अच्छा फिट लगते हैं जो समानांतर में कई मूल्यों पर काम कर सकते हैं।

(*) व्यवहार में, एकल-सटीक संख्याओं के साथ काम करते समय मध्यवर्ती संगणनाओं को धारण करने के लिए अक्सर डबल-परिशुद्धता मूल्यों का उपयोग करना सहायक होता है, इसलिए ऐसे सभी कार्यों के लिए टाइपकास्ट का उपयोग करना कष्टप्रद हो सकता है। भाषाएं "फ़ज़ी डबल" प्रकार होने से मदद कर सकती हैं, जो गणना को डबल के रूप में प्रदर्शित करेगी, और स्वतंत्र रूप से और एकल से डाली जा सकती है; यह विशेष रूप से सहायक होगा यदि फ़ंक्शन जो प्रकार doubleऔर वापसी के मापदंडों को लेते doubleहैं, उन्हें चिह्नित किया जा सकता है ताकि वे स्वचालित रूप से एक अधिभार उत्पन्न करें जो इसके बजाय "फजी डबल" को स्वीकार करता है और वापस करता है।


2

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

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


लंबाई और परिशुद्धता निर्दिष्ट करना बहुत कम है जो उपयोगी है। फिक्स्ड-पॉइंट बेस 10 होने से फाइनेंशियल प्रोसेसिंग के लिए उपयोगी होगा, जो लोगों को फ्लोटिंग-पॉइंट से मिलने वाले बहुत सारे आश्चर्य को दूर करेगा।
डेविड थॉर्नले

@ डेविड - शायद मुझे कुछ याद आ रहा है, लेकिन एक निश्चित-बिंदु आधार 10 डेटा प्रकार कैसे अलग है जो मैं यहाँ प्रस्तावित कर रहा हूँ? मेरे उदाहरण में एक फ्लोट (2) एक निश्चित 2 दशमलव अंक होगा और स्वचालित रूप से निकटतम सौवें दौर में होगा जो कि आप सरल वित्तीय गणना के लिए उपयोग करेंगे। अधिक जटिल गणनाओं के लिए आवश्यक होगा कि डेवलपर बड़ी संख्या में दशमलव अंकों को आवंटित करे।
जस्टिन केव

1
आप जो वकालत कर रहे हैं वह प्रोग्रामर-निर्दिष्ट परिशुद्धता के साथ एक निश्चित-बिंदु आधार 10 डेटा प्रकार है। मैं कह रहा हूं कि प्रोग्रामर-निर्दिष्ट परिशुद्धता ज्यादातर व्यर्थ है, और मैं केवल उन त्रुटियों के प्रकार को जन्म दूंगा, जिन्हें मैं COOLOL कार्यक्रमों में चलाता था। (उदाहरण के लिए, जब आप वेरिएबल्स की सटीकता को बदलते हैं, तो एक वेरिएबल को मिस करना आसान होता है, जिससे वैल्यू रन होती है। दूसरे के लिए, यह इंटरमीडिएट रिजल्ट साइज के बारे में बहुत अच्छा लगेगा।)
डेविड थॉर्नले

4
Float(2)आप की तरह एक प्रस्ताव को नहीं बुलाया जाना चाहिए Float, क्योंकि यहां कुछ भी नहीं चल रहा है, निश्चित रूप से "दशमलव बिंदु" नहीं है।
पाओलो एबरमन

1
  • भाषाओं में दशमलव प्रकार का समर्थन है; बेशक यह वास्तव में समस्या को हल नहीं करता है, फिर भी आपके पास उदाहरण के लिए कोई सटीक और परिमित प्रतिनिधित्व नहीं है solve;
  • कुछ DBs और चौखटे में मनी टाइप का समर्थन होता है, यह मूल रूप से पूर्णांक के रूप में सेंट की संख्या को संग्रहीत करता है;
  • तर्कसंगत संख्याओं के समर्थन के लिए कुछ पुस्तकालय हैं; वह ⅓ की समस्या हल करता है, लेकिन उदाहरण के लिए the2 की समस्या को हल नहीं करता है;

ये कुछ मामलों में ऊपर लागू होते हैं, लेकिन फ्लोट वैल्यू से निपटने के लिए वास्तव में एक सामान्य समाधान नहीं है। वास्तविक समाधान समस्या को समझना है और इससे निपटना सीखना है। यदि आप फ्लोट पॉइंट गणना का उपयोग कर रहे हैं, तो आपको हमेशा जांचना चाहिए कि आपके एल्गोरिदम संख्यात्मक रूप से स्थिर हैं । गणित / कंप्यूटर विज्ञान का बहुत बड़ा क्षेत्र है जो समस्या से संबंधित है। इसे न्यूमेरिकल एनालिसिस कहा जाता है ।


1

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

फ्लोटिंग-पॉइंट अनुमानों को आयात करने के लिए डिज़ाइन किए गए कार्यों को स्पष्ट रूप से लेबल किया जाना चाहिए, और उस ऑपरेशन के लिए उपयुक्त मापदंडों के साथ प्रदान किया जाना चाहिए, जैसे:

Finance.importEstimate(float value, Finance roundingStep)

सामान्य रूप से फ़्लोटिंग पॉइंट के नुकसान से बचने का एकमात्र वास्तविक तरीका शिक्षा है - प्रोग्रामर्स को कुछ समझने और समझने की ज़रूरत है जैसे फ्लोटिंग-पॉइंट अंकगणित के बारे में हर प्रोग्रामर को क्या जानना चाहिए

कुछ चीजें जो मदद कर सकती हैं, हालांकि:

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

-1

अधिकांश प्रोग्रामर आश्चर्यचकित होंगे कि COBOL को वह अधिकार मिला है ... COBOL के पहले संस्करण में कोई फ़्लोटिंग पॉइंट नहीं था, केवल दशमलव था, और COBOL में परंपरा आज तक जारी है कि पहली चीज़ जिसे आप संख्या घोषित करते समय सोचते हैं कि दशमलव है। .. फ़्लोटिंग पॉइंट का उपयोग केवल तभी किया जाएगा जब आपको वास्तव में इसकी आवश्यकता होगी। जब सी के साथ आया, किसी कारण से, कोई आदिम दशमलव प्रकार नहीं था, इसलिए मेरी राय में, यही वह जगह है जहां सभी समस्याएं शुरू हुईं।


1
C में दशमलव प्रकार नहीं था क्योंकि यह आदिम नहीं है, बहुत कम कंप्यूटरों में किसी भी प्रकार के हार्डवेयर दशमलव निर्देश होते हैं। आप पूछ सकते हैं कि बुनियादी और पास्कल के पास ऐसा क्यों नहीं था, क्योंकि वे धातु के करीब नहीं थे। COBOL और PL / I केवल एक ऐसी भाषा है जिसे मैं उस समय के बारे में जानता हूं जिसमें ऐसा कुछ भी था।
डेविड थॉर्नले

3
@JoelFan: तो आप COBOL में o कैसे लिखते हैं? दशमांश किसी भी समस्या को हल नहीं करता है, बेस 10 आधार 2 के रूप में गलत है।
vartec

2
दशमलव सटीक रूप से डॉलर और सेंट का प्रतिनिधित्व करने की समस्या को हल करता है, जो "बिजनेस ओरिएंटेड" भाषा के लिए उपयोगी है। लेकिन अन्यथा, दशमलव बेकार है; बहुत धीमी होने के दौरान इसमें एक ही तरह की त्रुटियां हैं (जैसे, 1/3 * 3 = 0.99999999) । यही कारण है कि यह उन भाषाओं में डिफ़ॉल्ट नहीं है जिन्हें विशेष रूप से लेखांकन के लिए डिज़ाइन नहीं किया गया था।
dan04

1
और फोरट्रान, जो एक दशक से अधिक समय तक सी की भविष्यवाणी करता है, उसके पास मानक दशमलव समर्थन भी नहीं है।
dan04

1
@JoelFan: यदि आपके पास त्रैमासिक मूल्य है और आपको प्रति माह मान की आवश्यकता है, तो अनुमान लगाएं कि आपको इसे किस से गुणा करना है ... नहीं, यह 0.33 नहीं है, यह an है।
वार्तेक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.