2010-04-02 30 views
17

मैं MySQL डेटाबेस स्कीमा में फ़्लोटिंग पॉइंट कॉलम को पेश करके एक समस्या में भाग गया कि फ़्लोटिंग पॉइंट मानों की तुलना हमेशा सही परिणामों को वापस नहीं करती है।MySQL फ़्लोटिंग पॉइंट तुलना मुद्दों

1 - 50.12
2 - 34.57
3 - 12.75
4 - ... (आराम 12.00 की तुलना में सभी कम)

SELECT COUNT(*) FROM `users` WHERE `points` > "12.75" 

यह रिटर्न मुझे "3"।

मैंने पढ़ा है कि MySQL में फ़्लोटिंग पॉइंट मानों की तुलना एक बुरा विचार है और दशमलव प्रकार बेहतर विकल्प है।

क्या मुझे फ्लोट प्रकार के साथ आगे बढ़ने की उम्मीद है और तुलना सही ढंग से काम करने के लिए मिलता है?

+0

में ऐसे विसंगतियों के लिए एक स्पष्ट कारण की तरह नहीं लगता है एसक्यूएल में डबल उद्धरण चिह्नों में किस प्रकार के अक्षर संलग्न हैं? – Joey

+1

दुर्भाग्यवश, MySQL डबल कोट्स को डिफ़ॉल्ट रूप से सिंगल-कोट्स की तरह कार्य करने की अनुमति देता है। यह सुविधा 'ANSI_QUOTES' विकल्प के साथ बंद की जा सकती है, जो उन्हें एएनएसआई एसक्यूएल मानक (उपर्युक्त क्वेरी में गैर-मानक बैकटिक्स की तरह) के अनुसार पहचानकर्ताओं को संदर्भित करेगी। – bobince

+1

12.75 बाइनरी (1100.11) में बिल्कुल प्रतिनिधित्व योग्य है, इसलिए मुझे नहीं लगता कि यह परीक्षण "> 12.75" कैसे पास करता है। क्या आप सुनिश्चित हैं कि आपकी सूची में कोई अन्य बिंदु> 12.75 नहीं है? –

उत्तर

23

क्या आप नीचे दी गई समस्या को देखते हैं?

CREATE TABLE a (num float); 

INSERT INTO a VALUES (50.12); 
INSERT INTO a VALUES (34.57); 
INSERT INTO a VALUES (12.75); 
INSERT INTO a VALUES (11.22); 
INSERT INTO a VALUES (10.46); 
INSERT INTO a VALUES (9.35); 
INSERT INTO a VALUES (8.55); 
INSERT INTO a VALUES (7.23); 
INSERT INTO a VALUES (6.53); 
INSERT INTO a VALUES (5.15); 
INSERT INTO a VALUES (4.01); 

SELECT SUM(num) FROM a; 
+-----------------+ 
| SUM(num)  | 
+-----------------+ 
| 159.94000005722 | 
+-----------------+ 

कुछ पंक्तियों के बीच एक अतिरिक्त 0.00000005722 फैल गया है। इसलिए उन मूल्यों में से कुछ मूल्यों की तुलना में झूठी वापसी करेंगे जब वे मूल्य के साथ शुरू किए गए थे।

ALTER TABLE a MODIFY num DECIMAL(6,2); 

SELECT SUM(num) FROM a; 
+----------+ 
| SUM(num) | 
+----------+ 
| 159.94 | 
+----------+ 
1 row in set (0.00 sec) 
+0

हे डैनियल! धन्यवाद। मैं अपने कॉलम प्रकार को डेसिमल में परिवर्तित करने पर विचार कर रहा हूं। –

+1

@ शरीफ: यदि 'DECIAML' में परिवर्तित करना असंभव है, तो केवल एकमात्र विकल्प यह है कि मैं फ़्लोटिंग पॉइंट तुलना के लिए कुछ सहिष्णुता की अनुमति देना चाहता हूं, जैसे कि आप अपनी क्वेरी को निम्न प्रकार से लिख सकते हैं:' उपयोगकर्ताओं से चुनें COUNT (*) जहां अंक> (12.75 + 0.001); '... हालांकि यदि सटीकता सर्वोपरि है, तो निश्चित बिंदु' DECIMAL' जाने का तरीका है। 'DECIMAL' का एक अन्य विकल्प सौंपा के संदर्भ में आपके मूल्यों का प्रतिनिधित्व करने के लिए एक पूर्णांक मान का उपयोग कर सकता है:' 50.12' के बजाय '5012'। ऐसी कुछ स्थितियां हो सकती हैं जहां यह उचित हो। –

+0

मैंने सहिष्णुता को पहले से ही जोड़ने का प्रयास किया है, वैसे ही आपने इसका उल्लेख भी किया है, फिर भी परिणाम कभी भी सुसंगत नहीं थे। –

1

यह एक फ़्लोटिंग पॉइंट है, तो समस्या क्या है? 3 सही परिणाम हो सकता है, यह निर्भर करता है कि डेटाबेस 12.75 के बारे में क्या सोचता है। क्या यह 12.75 या थोड़ा और है?

यदि आप सटीक संख्या चाहते हैं तो DECIMAL का उपयोग करें।

+0

हाय फ्रैंक, क्या आप "12.75 के बारे में सोचने वाले डेटाबेस" के बारे में क्या बताते हैं, इसका विस्तार कर सकते हैं। यदि मैं तीन अंकों की सटीकता के साथ दो अंकों के सटीक मूल्य की तुलना करने की कोशिश करता हूं तो क्या मुझे परेशानी होगी। की तरह ... 'उपयोगकर्ता' से चुनें COUNT (*) 'अंक'> 12.751 " –

+0

@ शरीफशिक मुझे लगता है कि अन्य उपयोगकर्ता अनुभवों से दशमलव को उस मामले को हल करना चाहिए। – gumuruh

1

समानता के लिए फ्लोट की तुलना में एक समस्या है। यह अप्रत्याशित परिणाम दे सकता है। यह फ्लोटिंग पॉइंट अंकगणित के आंतरिक कार्यान्वयन के कारण है।

0

एक स्ट्रिंग के साथ एक संख्या की तुलना?

2

मैं एक बार इसी तरह के मुद्दे का सामना किया:

फ्लोटिंग प्वाइंट गणित और तुलना के साथ समस्याओं से बचने के लिए, आपको DECIMAL डेटा प्रकार का उपयोग करना चाहिए। 'फ्लोट' फ़ील्ड को 'दशमलव' में कनवर्ट करें। यह निश्चित रूप से समस्या को हल करेगा।

+0

मैंने सोचा कि फ्लोट की सटीक निश्चित लंबाई का उपयोग करके समस्या हल हो चुकी है, इसलिए यह नहीं है ?? उदाहरण के लिए; मैं फ्लोट (4,2) परिभाषित करता हूं। और फिर मैंने 12.50 का मान संग्रहीत किया, और फिर मैं इसे "> 12.50" कथन के साथ तुलना करने का प्रयास करता हूं। क्या यह अभी भी असफल नहीं होगा? – gumuruh

1

मैं इस

WHERE abs(value - 12.75)<0.001 

है, लेकिन मैं मानता हूँ, किसी भी भाषा समानता नाव तुलना कर सकते हैं और यदि संग्रहीत मूल्यों सटीक संख्या के बराबर होती है क्या आप डाला महत्व देता है, वहाँ किसी भी मुद्दे

केवल एक जोड़े के साथ नहीं होना चाहिए decimals और सटीक मिलान मूल्यों के, सटीक त्रुटियों MySQL

संबंधित मुद्दे