दिलचस्प पोस्ट
रनएबल इंटरफ़ेस को कार्यान्वित करके तैयार किए गए धागे को कैसे रोकें? स्पिनर पाठ को फ़ॉन्ट कस्टम फ़ॉन्ट को कैसे सेट करना है? एएसपी.नेट एमवीसी में सत्र चर जावास्क्रिप्ट के साथ एक JSON ऑब्जेक्ट ट्री के सभी नोड्स को पार करें SQL में यादृच्छिक पंक्ति का अनुरोध कैसे करें? आईओएस वीओआईपी सॉकेट पृष्ठभूमि में नहीं चलेगा एएसपी.नेट 5 आईआईएस पर होस्टिंग परियोजना PHP से एचटीटीपी से HTTPS पर स्विच करते समय सत्र खो गया घटना धागा सुरक्षित रूप से उठाएं – सर्वोत्तम अभ्यास पीएचपी: उद्धरण चिह्नों में बचाए हुए अवतरणों को अनदेखा करने के लिए रेगेक्स जावास्क्रिप्ट का उपयोग करते हुए IFrame से क्रॉस डोमेन यूआरएल एक्सेस कैसे लागू हो सकता है? एक ही आईडी वाला कई तत्व एक सीएसएस आईडी चयनकर्ता को जवाब देते हैं मैं लोगों को वसंत MVC में XSS करने से कैसे रोकूं? बाश में फ़ाइल या स्टडीन से कैसे पढ़ा जाए? PDFBox के साथ पीडीएफ फाइलों को पार्स करना (विशेषकर तालिकाओं के साथ)

MATLAB में 24.0000 के बराबर 24.0000 क्यों नहीं है?

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

निम्न कोड में, intersections फ़ंक्शन को प्रतिच्छेदन बिंदु मिलते हैं:

 [points(:,1), points(:,2)] = intersections(... obj.modifiedVGVertices(1,:), obj.modifiedVGVertices(2,:), ... [vertex1(1) vertex2(1)], [vertex1(2) vertex2(2)]); 

परिणाम:

 >> points points = 12.0000 15.0000 33.0000 24.0000 33.0000 24.0000 >> vertex1 vertex1 = 12 15 >> vertex2 vertex2 = 33 24 

परिणाम से दो vertex1 ( vertex1 और vertex2 ) समाप्त कर दी जानी चाहिए। यह निम्न कमांडों द्वारा किया जाना चाहिए:

 points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)), :); points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)), :); 

ऐसा करने के बाद, हमारे पास यह अप्रत्याशित परिणाम है:

 >> points points = 33.0000 24.0000 

इसका परिणाम रिक्त मैट्रिक्स होना चाहिए। जैसा कि आप देख सकते हैं, [33.0000 24.0000] की पहली (या दूसरी?) जोड़ी समाप्त हो गई है, लेकिन दूसरी नहीं

फिर मैंने इन दो भावों की जाँच की:

 >> points(1) ~= vertex2(1) ans = 0 >> points(2) ~= vertex2(2) ans = 1 % <-- It means 24.0000 is not equal to 24.0000? 

समस्या क्या है?


अधिक आश्चर्य की बात है, मैंने एक नई स्क्रिप्ट बनाई है जिसमें केवल इन कमांड हैं:

 points = [12.0000 15.0000 33.0000 24.0000 33.0000 24.0000]; vertex1 = [12 ; 15]; vertex2 = [33 ; 24]; points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)), :); points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)), :); 

अपेक्षित परिणाम:

 >> points points = Empty matrix: 0-by-2 

वेब के समाधान से एकत्रित समाधान "MATLAB में 24.0000 के बराबर 24.0000 क्यों नहीं है?"

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

वास्तविक बनाम प्रदर्शन सटीक

अब प्रश्न में विशिष्ट उदाहरण को संबोधित करने के लिए … जबकि 24.0000 और 24.0000 को उसी तरीके से प्रदर्शित किया जाता है, यह पता चला है कि वे वास्तव में इस मामले में बहुत छोटी दशमलव राशि से अलग हैं। आप इसे नहीं देखते हैं क्योंकि MATLAB केवल डिफाल्ट के द्वारा 4 महत्वपूर्ण अंक दिखाता है , समग्र प्रदर्शन साफ ​​और सुव्यवस्थित रखते हुए। यदि आप पूर्ण परिशुद्धता देखना चाहते हैं, तो आपको या तो format long आदेश जारी करना चाहिए या संख्या का एक हेक्साडेसिमल प्रस्तुति देखना चाहिए:

 >> pi ans = 3.1416 >> format long >> pi ans = 3.141592653589793 >> num2hex(pi) ans = 400921fb54442d18 

शुरुआती मूल्य बनाम गणना मूल्य

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

 >> a=sum([0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]); % Sum 10 0.1s >> b=1; % Initialize to 1 >> a == b ans = logical 0 % They are unequal! >> num2hex(a) % Let's check their hex representation to confirm ans = 3fefffffffffffff >> num2hex(b) ans = 3ff0000000000000 

सही तरीके से फ़्लोटिंग-पॉइंट तुलना कैसे करें

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

 a = 24; b = 24.000001; tolerance = 0.001; if abs(ab) < tolerance, disp('Equal!'); end 

प्रदर्शित होगा "समान!"

फिर आप अपना कोड बदल सकते हैं:

 points = points((abs(points(:,1)-vertex1(1)) > tolerance) | ... (abs(points(:,2)-vertex1(2)) > tolerance),:) 

फ़्लोटिंग-बिंदु प्रतिनिधित्व

फ्लोटिंग-पॉइंट अंक (और विशेष रूप से फ़्लोटिंग-पॉइंट अरिथ्मेटिक के लिए आईईईई 754 मानक ) का अच्छा अवलोकन है जो हर कम्प्यूटर वैज्ञानिक को डेविड गोल्डबर्ग द्वारा फ्लोटिंग-पॉइंट अंकगणित के बारे में पता होना चाहिए

एक बाइनरी फ़्लोटिंग-पॉइंट संख्या वास्तव में तीन पूर्णांकियों द्वारा दर्शायी जाती है: एक संकेत बिट्स, एक महत्व (या गुणांक / अंश) b , और एक एक्सपोनेंट e । डबल-स्पेसिफिक फ्लोटिंग-प्वाइंट प्रारूप के लिए , प्रत्येक संख्या को स्मृति में 64 बिट्स के रूप में प्रदर्शित किया जाता है:

यहां छवि विवरण दर्ज करें

वास्तविक मान को निम्न सूत्र के साथ मिल सकता है:

यहां छवि विवरण दर्ज करें

यह प्रारूप 10 ^ -308 से लेकर 10 ^ 308 तक की संख्या के प्रतिनिधित्व के लिए अनुमति देता है। MATLAB के लिए आप इन सीमाओं को realmin और realmax realmin से प्राप्त कर सकते हैं:

 >> realmin ans = 2.225073858507201e-308 >> realmax ans = 1.797693134862316e+308 

चूंकि एक अस्थायी बिंदु संख्या का प्रतिनिधित्व करने के लिए उपयोग की जाने वाली बिट्स की एक सीमित संख्या है, इसलिए केवल बहुत से परिमित संख्याएं हैं जो उपर्युक्त श्रेणी के भीतर प्रदर्शित की जा सकती हैं। कम्प्यूटेशंस अक्सर ऐसे मूल्य का परिणाम देगा जो कि इन परिमित अभ्यावेदनों में से किसी एक से मेल नहीं खाता है, इसलिए मूल्यों को गोल होना चाहिए। ये मशीन-सटीक त्रुटियां अलग-अलग तरीकों से खुद को स्पष्ट करती हैं, जैसा कि ऊपर दिए गए उदाहरणों में चर्चा की गई है।

इन राउंड-ऑफ त्रुटियों को बेहतर ढंग से समझने के लिए, फ़ंक्शन eps द्वारा प्रदान की गई रिश्तेदार फ्लोटिंग-पॉइंट सटीकता को देखने के लिए उपयोगी है, जो किसी दिए गए संख्या से दूरी को अगले सबसे बड़े फ़्लोटिंग-पॉइंट प्रस्तुति के लिए बराबर करता है:

 >> eps(1) ans = 2.220446049250313e-16 >> eps(1000) ans = 1.136868377216160e-13 

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

 >> format long % Display full precision >> x = rand(1, 10); % Get 10 random values between 0 and 1 >> a = mean(x) % Take the mean a = 0.587307428244141 >> b = mean(x+10000)-10000 % Take the mean at a different scale, then shift back b = 0.587307428244458 

ध्यान दें कि जब हम रेंज [0 1] से रेंज [10000 10001] से x के मूल्यों को स्थानांतरित करते हैं, तो एक मतलब की गणना करें, फिर तुलना के लिए औसत ऑफसेट घटाएं, हमें एक ऐसा मान मिलता है जो पिछले 3 महत्वपूर्ण अंकों के लिए अलग है। यह दिखाता है कि डेटा की ऑफसेट या स्केलिंग कैसे किया जाता है, उस पर की गई गणना की सटीकता को बदल सकता है, जो कि कुछ समस्याओं के लिए जिम्मेदार है।

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

प्रकार

 format long g 

यह कमांड संख्या के पूर्ण मूल्य को दिखाएगा। यह 24.00000021321 जैसा कुछ होने की संभावना है! = 24.00000123124

लिखने का प्रयास करें

0.1 + 0.1 + 0.1 == 0.3

चेतावनी: आप परिणाम के बारे में आश्चर्यचकित हो सकते हैं!

हो सकता है कि दो नंबर वास्तव में 24.0 और 24000000001 हैं लेकिन आप सभी दशमलव स्थानों को नहीं देख रहे हैं।

Matlab EPS फ़ंक्शन की जांच http://matlab.izmiran.ru/help/techdoc/ref/eps.html

Matlab अस्थायी अंक गणित 16 अंकों के सटीक (केवल 5 दिखाए जाते हैं) का उपयोग करता है।