2009-07-02 21 views
9

मैंने परिशुद्धता हानि को कम करने के लिए फ़्लोटिंग पॉइंट गणनाओं के साथ कुछ परीक्षण किया। मैं एक ऐसी घटना में ठोकर खाई जिसे मैं यहां दिखाना चाहता हूं और उम्मीद करता हूं कि एक स्पष्टीकरण प्राप्त करें।एसक्यूएल सर्वर: संख्यात्मक अक्षरों के साथ गणना

जब मैं

print 1.0/(1.0/60.0) 

लिखने परिणाम

60.0024000960 

है जब मैं एक ही सूत्र लिखने और float

print cast(1.0 as float)/(cast(1.0 as float)/cast(60.0 as float)) 

को स्पष्ट कास्टिंग कर परिणाम

है

अब तक मैंने सोचा कि दशमलव स्थानों के साथ संख्यात्मक शाब्दिक स्वचालित रूप से उचित परिशुद्धता के साथ float मूल्यों के रूप में माना जाता है। real पर कास्टिंग float पर कास्टिंग के समान परिणाम दिखाता है।

  • क्या SQL सर्वर संख्यात्मक अक्षरों का मूल्यांकन करने के बारे में कुछ दस्तावेज है?
  • इनमें से कौन सा डेटाटाइप है?
  • क्या मुझे वास्तव में उन्हें float पर बेहतर परिशुद्धता प्राप्त करना है (जो मुझे विडंबना की तरह लगता है :)?
  • क्या मेरे सूत्रों को कास्ट के साथ छेड़छाड़ करने का कोई आसान तरीका है?

उत्तर

9

SQL सर्वर सबसे छोटी संभव डेटाटाइप का उपयोग करता है।

जब आप इस स्क्रिप्ट

SELECT SQL_VARIANT_PROPERTY(1.0, 'BaseType') 
SELECT SQL_VARIANT_PROPERTY(1.0, 'Precision') 
SELECT SQL_VARIANT_PROPERTY(1.0, 'Scale') 
SELECT SQL_VARIANT_PROPERTY(1.0, 'TotalBytes') 

चलाने आपको लगता है कि एसक्यूएल सर्वर परोक्ष एक NUMERIC (2, 1) डेटाप्रकार उपयोग देखेंगे।
60.0 द्वारा विभाजन परिणामस्वरूप NUMERIC (8, 6) में परिवर्तित हो जाता है।
अंतिम गणना परिणाम को NUMERIC (17, 10) में परिवर्तित करती है।


संपादित

दशमलव बिंदु के साथ एक निरंतर एसक्यूएल सर्वर पुस्तकें ऑनलाइन Data Type Conversion से

Transact SQL कथन में, ले ली स्वचालित रूप से एक संख्यात्मक डेटा मूल्य में परिवर्तित कर दिया है, न्यूनतम परिशुद्धता और स्केल आवश्यक का उपयोग कर आवश्यक है। उदाहरण के लिए, निरंतर 12.345 5 का एक सटीक और 3.

+0

आह .. मुझे अब तक उस विधि को नहीं पता था। बहुत बहुत धन्यवाद :) – VVS

+0

तो अपेक्षित परिणाम प्राप्त करने के लिए एक स्पष्ट कलाकार के आसपास कोई रास्ता नहीं है? एसक्यूएल सर्वर को बताने का कोई और तरीका है कि दिया गया शाब्दिक प्रकार (उदा।) फ्लोट है? – VVS

+0

@VVS, जैसा कि आप पहले से ही कर रहे हैं, एक स्पष्ट कलाकार के अलावा, मुझे पता नहीं है। एसक्यूएल सर्वर हमेशा मूल्य को संख्यात्मक के रूप में समझता है।अगर आप अपने मूल्यों को 1.000000000000000000000000000000000000 जैसे सटीक जोड़ते हैं तो समस्या को थोड़ा कम किया जा सकता है। –

4

हाँ की एक पैमाने के साथ एक अंकीय मान में बदल जाता है, तो आप अक्सर उन्हें कास्ट करने के लिए बेहतर परिशुद्धता प्राप्त फ्लोट करने के लिए किया है।इस पर मेरी ले:

For better precision cast decimals before calculations

+0

लेख में तर्क गलत है। यह कुछ मनमाना मूल्यों पर आधारित है। दशमलव प्रकार के पक्ष में काउंटर उदाहरण ढूंढना आसान होगा। एक अनुभवजन्य उदाहरण के आधार पर ये भारतीय दावे अपने आप में जाल हैं। – f470071

3

मैं इसे समझा जाना चाहिए कि क्या इसी तरह के मामलों में भविष्य में संदर्भ के लिए पर्दे के पीछे चल रहा है लगता है।

वैज्ञानिक नोटेशन को छोड़कर दशमलव बिंदु के साथ शाब्दिक संख्यात्मक मान दशमलव डेटा प्रकार का प्रतिनिधित्व करते हैं जो सबसे कम संभव दशमलव प्रकार के रूप में संग्रहीत किया जाता है। Lieven Keersmaekers के रूप में एक ही बोली से: https://msdn.microsoft.com/en-us/library/ms191530%28SQL.90%29.aspx#_decimal

Transact SQL कथन में, एक दशमलव बिंदु के साथ एक निरंतर स्वचालित रूप से एक संख्यात्मक डेटा मूल्य में बदल जाता है, कम से कम परिशुद्धता और बड़े पैमाने आवश्यक का उपयोग कर। उदाहरण के लिए, निरंतर 12.345 5 का एक सटीक और दशमलव बिंदु के दाईं पैमाने निर्दिष्ट पर 3.

अनुगामी शून्य के पैमाने के साथ एक अंकीय मान में परिवर्तित कर दिया है। दशमलव बिंदु से छोड़े गए प्रमुख शून्यों को नजरअंदाज कर दिया जाता है।

कुछ उदाहरण:

1.0 -> Decimal(2,1) 
60.0 -> Decimal(3,1) 
1.00 -> Decimal(3,2) 
01.0 -> Decimal (2,1) 

एक और मुद्दा विचार करने के लिए Data Type precedence है। जब कोई ऑपरेटर विभिन्न डेटा प्रकारों के दो अभिव्यक्तियों को जोड़ता है, तो डेटा प्रकार की प्राथमिकता के नियम निर्दिष्ट करते हैं कि निम्न प्राथमिकता वाला डेटा प्रकार उच्च प्राथमिकता वाले डेटा प्रकार में परिवर्तित हो जाता है। और फिर भी एक अन्य बिंदु पर विचार करना है कि अगर हम दशमलव प्रकारों पर अंकगणितीय परिचालन करते हैं जो परिणामस्वरूप दशमलव प्रकार, यानी परिशुद्धता और पैमाने दोनों ऑपरेटरों और संचालन पर निर्भर करते हैं। यह दस्तावेज़ Precision, Scale, and Length में वर्णित है।

तो, कोष्टक

(1.0/60.0) is evaluated to 0.016666 and the resulting type is Decimal (8,6) 

में अपनी अभिव्यक्ति का हिस्सा प्रेसिजन और दशमलव भाव के पैमाने के बारे में नियम से ऊपर का उपयोग कर। इसके अलावा बैंकर के गोलाकार या गोल करने के लिए भी उपयोग किया जाता है। दशमलव और फ्लोट प्रकार के लिए अलग-अलग गोलियों को नोट करना महत्वपूर्ण है। हम अभिव्यक्ति

1.0/0.016666 is evaluated to 60.002400096 and the resulting type is Decimal (17,10) 

जारी रखते हैं तो विसंगति का हिस्सा अलग राउंडिंग के कारण नाव के लिए की तुलना में दशमलव प्रकार के लिए इस्तेमाल किया जा रहा है।

उपर्युक्त नियमों के अनुसार यह केवल एक कलाकार को ब्रांड्स के अंदर उपयोग करने के लिए पर्याप्त होगा। डेटा टाइप प्राथमिकता नियमों के अनुसार प्रत्येक अन्य शाब्दिक को फ्लोट करने के लिए प्रोत्साहित किया जाएगा।

1.0/(1.0/cast(60.0 as float)) 

और एक और महत्वपूर्ण बात। यहां तक ​​कि यह फ्लोट अभिव्यक्ति सटीक परिणाम की गणना नहीं करती है। यह इतना है कि फ्रंट एंड (एसएसएमएस या जो कुछ भी) मान को राउंड करता है (मुझे लगता है) परिशुद्धता 6 अंक और फिर पीछे शून्यों को छोटा करता है। तो यानी 1.000001 बन जाता है 1.

सरल, है ना?