तैरने का गैर-निर्धारक योग


10

मुझे स्पष्ट मुट्ठी के बारे में बताएं: मैं पूरी तरह से समझता हूं कि फ्लोटिंग पॉइंट प्रकार दशमलव मानों का सही प्रतिनिधित्व नहीं कर सकते हैं । इस बारे में नहीं है! फिर भी, फ्लोटिंग पॉइंट गणना को नियतात्मक माना जाता है

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

CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);

SELECT STR(SUM(#someFloats.val), 30, 15) FROM #someFloats;

DROP TABLE #someFloats;

-- yields:
--   13.600000000000001

अब तक, इतना अच्छा - यहां कोई आश्चर्य नहीं। हम सभी जानते हैं कि 1.2बाइनरी प्रतिनिधित्व में बिल्कुल प्रतिनिधित्व नहीं किया जा सकता है, इसलिए "अभेद्य" परिणाम अपेक्षित है।

अब निम्नलिखित अजीब बात तब होती है जब मैं एक और तालिका छोड़ता हूं:

CREATE TABLE #A (a int);
INSERT INTO #A (a) VALUES (1), (2);

CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);

SELECT #A.a, STR(SUM(#someFloats.val), 30, 15)
  FROM #someFloats LEFT JOIN #A ON 1 = 1
 GROUP BY #A.a;

DROP TABLE #someFloats;
DROP TABLE #A;

-- yields
--   1   13.600000000000001
--   2   13.599999999999998

( sql fiddle , आप वहां निष्पादन योजना भी देख सकते हैं)

मेरे पास समान मूल्यों पर समान राशि है , लेकिन एक अलग फ़्लोटिंग-पॉइंट त्रुटि है। यदि मैं तालिका में अधिक पंक्तियों को जोड़ता हूं , तो हम देख सकते हैं कि मूल्य उन दो मूल्यों के बीच वैकल्पिक है। मैं केवल एक के साथ इस मुद्दे को पुन: पेश करने में सक्षम था ; उम्मीद के मुताबिक काम करता है।#ALEFT JOININNER JOIN

क्योंकि इसका मतलब एक है कि यह असुविधाजनक है DISTINCT, GROUP BYया PIVOTउन्हें विभिन्न मूल्यों के रूप में देखता (जो वास्तव में है कि कैसे हम इस मुद्दे की खोज की)।

स्पष्ट समाधान मूल्य को गोल करना है, लेकिन मैं उत्सुक हूं: क्या इस व्यवहार के लिए एक तार्किक स्पष्टीकरण है?

जवाबों:


15

दरअसल, जिस लिंक का आप जिक्र कर रहे हैं, वह यह नहीं कहता कि फ्लोटिंग पॉइंट अंकगणितीय गणना हमेशा नियतात्मक होती है। वास्तव में, एक उत्तर में यह उल्लेख किया गया है कि जोड़ साहचर्य नहीं है (मतलब (a + b) + cजरूरी नहीं के बराबर a + (b + c)), जिसे इस उत्तर में भी कहा गया है ।

यदि स्ट्रीम एकत्रीकरण प्रत्येक समूह की पंक्तियों को अलग-अलग क्रम में संसाधित करने के लिए होता है - जो SQL सर्वर आमतौर पर करने के लिए स्वतंत्र है; यदि ORDER BYउपयुक्त क्लॉज में नहीं है, तो ऑप्टिमाइज़र जो भी स्कैन या तलाश करेगा या अन्य क्वेरी ऑपरेटर सबसे तेज़ होगा, वह इस बात की परवाह किए बिना कि किस क्रम में परिवर्धन करता है - तब यह आपके द्वारा देखे गए व्यवहार की व्याख्या कर सकता है।

जोड़ हमेशा निर्धारक होता है: आप एक ही दो फ्लोट में डालते हैं, आप एक ही फ्लोट बाहर निकालते हैं। लेकिन एक अलग क्रम में एक साथ तैरने को जोड़ने से एक अलग परिणाम मिल सकता है।


सहकारिता का नियतत्ववाद से कोई संबंध नहीं है, इसलिए कि बिट भ्रामक है।
मूंग बतख

फ्लोटिंग पॉइंट जोड़ की गैर- SUM()समरूपता SQL सर्वर एग्रीगेट फ़ंक्शन के गैर-निर्धारक व्यवहार की ओर ले जाती है , क्या आप @MooingDuck से सहमत होंगे?
मस्टीको

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

इंटेगर डिवीजन SUM()फ्लोटिंग पॉइंट आर्ग्युमेंट्स पर SQL सर्वर के लिए एक प्रतिरूप है, वास्तव में कैसे?
मस्टीको

1
पूर्णांक विभाजन गैर-सहयोगी और नियतात्मक है। इसलिए, अंकगणित संचालन समरूपता नियतावाद से संबंधित नहीं है। इसलिए किसी भी गैर- SUM()समरूपता को दृढ़ संकल्प के प्रति अप्रासंगिक होना चाहिए। मैं मानता हूं कि SUMयह गैर निर्धारक प्रतीत होता है, लेकिन आपको सहसंबंध के उल्लेखों को हटा देना चाहिए, क्योंकि यह असंबंधित है।
मूकिंग डक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.