SQL सर्वर में एक अजीब ऑपरेशन समस्या: -100 / -100 * 10 = 0


106
  • यदि आप SELECT -100/-100*10परिणाम निष्पादित करते हैं 0
  • यदि आप SELECT (-100/-100)*10परिणाम निष्पादित करते हैं 10
  • यदि आप SELECT -100/(-100*10)परिणाम निष्पादित करते हैं 0
  • यदि आप SELECT 100/100*10परिणाम निष्पादित करते हैं 10

बोल राज्यों:

जब एक अभिव्यक्ति में दो ऑपरेटरों का एक ही ऑपरेटर पूर्वता स्तर होता है, तो उन्हें अभिव्यक्ति में उनकी स्थिति के आधार पर बाएं से दाएं मूल्यांकन किया जाता है।

तथा

Level   Operators
  1     ~ (Bitwise NOT)
  2     * (Multiplication), / (Division), % (Modulus)
  3     + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)

BOL गलत है, या मैं कुछ याद कर रहा हूँ? ऐसा लगता -है कि (अपेक्षित) पूर्वता को फेंक रहा है।


7
आपका सवाल क्या हैं?
इलेसेस

14
आपको क्या लगता है कि आपको बिट्स के साथ क्या करना है, आप पूर्णांक के साथ काम कर रहे हैं। और पूर्णांक / पूर्णांक = पूर्णांक। तो -100 / -1000 0 है
सेप्टिक

5
ठीक है, मैं सहमत हूं, कि -यह प्रवाह "गलत" होने का कारण बनता है। यदि आप कोशिश -100/(-100)*10करते हैं तो आपको परिणाम मिलता है 10। ऐसा लगता है कि समीकरण में /मूल्य के खिलाफ लागू किया जा रहा -है और फिर समीकरण 100*10निर्धारित किया जा रहा है। मुझे यकीन नहीं है कि यह BOL के साथ एक त्रुटि है, लेकिन अधिक है कि SQL सर्वर अपेक्षित रूप से व्यवहार नहीं कर रहा है। यह sql-docs पर एक मुद्दा उठाने और देखने के लायक हो सकता है कि उनकी प्रतिक्रिया क्या है; शायद "सुविधा" की सलाह देने वाले दस्तावेज़ में एक नोट जोड़ा जा सकता है।
लारनु

3
SELECT -100/(-100)*10यह भी लौटाता है। 10. ऐसा लगता -है कि -ऑपरेटर के रूप में व्यवहार किया जाता है जिसे 100*10गणना करने के बाद ही लागू किया जाना चाहिए
Panagiotis Kanavos

7
A / -B * Cहै A <div> <negate> B <multiply> C। डॉक्स की तुलना में नेगेट की मिसाल कम है, इसलिए इसका परिणाम है A / -(B * C)। आप अस्थायी स्थिरांक का उपयोग करके इसे और अधिक स्पष्ट रूप से देख सकते हैं: 12e / -13e * 14eबनाम 12e / (-13e) * 14eबनाम 12e / 13e * 14e। इसका कारण यह है कि हमें फेंकता है क्योंकि हम आम तौर पर अनैतिक माइनस से शाब्दिक का हिस्सा बनने की उम्मीद करते हैं, या कम से कम बहुत अधिक पूर्वता है, लेकिन यह नहीं है कि टी-एसक्यूएल कैसे काम करता है।
जीरोन मोस्टर्ट

जवाबों:


96

पूर्वता तालिका के अनुसार, इस है अपेक्षित व्यवहार। कम वरीयता (अपर ) के साथ ऑपरेटर से पहले उच्च वरीयता ( /और *) वाले ऑपरेटर का मूल्यांकन किया जाता है -। तो यह:

-100 / -100 * 10

इस रूप में मूल्यांकन किया जाता है:

-(100 / -(100 * 10))

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


38
वाह, टी-एसक्यूएल में एक और मणि सुविधा :) मुझे लगता है कि मुझे बग की खोज करने के लिए अब अपने सभी कोड का ऑडिट करना होगा।
usr

14
ओह यार। यह विभिन्न PHP ternary ऑपरेटर बग बग्स .php.net/bug.php ? id=61915 से भी बदतर है । क्या समझदार लोग सोचते हैं कि एकतरफा ऑपरेटरों को द्विआधारी की तुलना में कम पूर्वता होना चाहिए?
phuclv

12
वास्तविक अंतर यह हो सकता है कि क्या -एक ऑपरेटर माना जाता है -100। कुछ भाषाओं में, यह एक पूर्णांक के वाक्य रचना का हिस्सा है।
बरमार

7
तो यह उनकी एकता की पूर्वता में एक बग है -
केविन

4
और काउंटर-सहज ज्ञान युक्त डिजाइन का विजेता है ...: Microsoft - एक बार फिर
rexkogitans

34

BOL सही है। -की तुलना में कम पूर्वता है *, इसलिए

-A * B

के रूप में पार्स किया जाता है

-(A * B)

गुणा किया जा रहा है कि यह क्या है, आप आम तौर पर इसे नोटिस नहीं करते हैं, सिवाय दो अन्य बाइनरी ऑपरेटरों में समान पूर्वता के साथ मिश्रण करते समय: /और %(और %इस तरह के यौगिक अभिव्यक्तियों में शायद ही कभी उपयोग किया जाता है)। इसलिए

C / -A * B

के रूप में पार्स किया जाता है

C / -(A * B)

परिणामों की व्याख्या करना। यह काउंटर सहज है, क्योंकि अधिकांश अन्य भाषाओं में, एकल शून्य से अधिक पूर्वता है *और /, लेकिन T-SQL में नहीं है, और इस सही ढंग से दर्ज है।

इसका वर्णन करने का एक अच्छा (?) तरीका:

SELECT -1073741824 * 2

एक अंकगणित अतिप्रवाह -(1073741824 * 2)पैदा करता है , क्योंकि 2147483648एक मध्यवर्ती के रूप में पैदा होता है, जो एक में फिट नहीं होता है INT, लेकिन

SELECT (-1073741824) * 2

अपेक्षित परिणाम पैदा करता है -2147483648, जो करता है।


"माइनस" द्विआधारी है। यूनरी -"नकारात्मक" है। जो लोग "ऋणात्मक 10" जैसी बातें कहते हैं, उनका मतलब "नकारात्मक 10" है, जो कि गलत है।
संचय

11
@ संचय: दोष मेरा नहीं है। -ऑपरेटर, जब एक संकार्य के लिए आवेदन किया, कहा जाता है MINUSSQL क्वेरी योजनाओं में। इसके बाइनरी समकक्ष को कहा जाता है SUB। यदि आप चाहें, तो "एकात्मक ऋणात्मक" की व्याख्या "शून्य से संचालक द्वारा हस्ताक्षरित" के लिए शॉर्टहैंड के रूप में करें - सिमेंटिक पदनाम के बजाए एक वाक्यात्मक।
जीरोने मोस्टर्ट

3
"नकारात्मक 10" मानक अमेरिकी उपयोग है (मेरा मानना ​​है) लेकिन यह यूके में मानक नहीं है।
Alchymist

12

प्रलेखन में ध्यान दें कि (शायद प्रति-सहज रूप से) - (Negative)तीसरे के लिए पूर्वता का क्रम है।

तो आप प्रभावी रूप से प्राप्त करें:

-(100/-(100*10)) = 0

यदि आप उन्हें वैरिएबल में रखते हैं, तो आप ऐसा होते हुए नहीं देखेंगे, क्योंकि कोई एकतरफा ऑपरेशन नहीं है जो गुणा के बाद होता है।

तो यहाँ A और B एक समान हैं, जबकि C, D, E आपको दिखाई देने वाला परिणाम दिखाते हैं (E के साथ पूर्ण कोष्ठक है)

DECLARE @i1 int, @i2 int, @i3 int;

SELECT @i1 = -100,
       @i2 = -100,
       @i3 = 10;

SELECT @i1/@i2*@i3      [A],
       -100/(-100)*10   [B],
       -100/-100*10     [C],
       -100/-(100*10)   [D],
       -(100/-(100*10)) [E];

A - 10
B - 10
C - 0
D - 0
E - 0
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.