समस्या:
आप (गैर-ऋणात्मक) शेष खोजना चाहते हैं।
उदाहरण:
तालिका में numbers
, आपके पास पूर्णांकों के दो स्तंभ हैं:a
और b
।
ए | <थ>बी|
---|---|
9 | 3 |
5 | 3 |
2 | 3 |
0 | 3 |
-2 | 3 |
-5 | 3 |
-9 | 3 |
5 | -3 |
-5 | -3 |
5 | 0 |
0 | 0 |
आप a
. को विभाजित करके शेषफलों की गणना करना चाहते हैं द्वारा b
. प्रत्येक शेष एक गैर-ऋणात्मक पूर्णांक मान b
. से छोटा होना चाहिए ।
समाधान 1 (पूरी तरह से सही नहीं):
SELECT a, b, a % b AS remainder FROM numbers;
नतीजा यह है:
ए | <थ>बी <थ>शेष||
---|---|---|
9 | 3 | 0 |
5 | 3 | 2 |
2 | 3 | 2 |
0 | 3 | 0 |
-2 | 3 | -2 |
-5 | 3 | -2 |
-9 | 3 | 0 |
5 | -3 | 2 |
-5 | -3 | -2 |
5 | 0 | त्रुटि |
0 | 0 | त्रुटि |
चर्चा:
यह समाधान सही ढंग से काम करता है यदि a गैर-ऋणात्मक है। हालांकि, जब यह ऋणात्मक होता है, तो यह शेष की गणितीय परिभाषा का पालन नहीं करता है।
संकल्पनात्मक रूप से, a
. के एक पूर्णांक विभाजन के बाद शेष बचता है द्वारा b
. गणितीय रूप से, शेष दो पूर्णांक एक गैर-ऋणात्मक पूर्णांक है जो भाजक b
से छोटा होता है . अधिक सटीक रूप से, यह एक संख्या r∈{0,1,...,b - 1} है जिसके लिए कुछ पूर्णांक k मौजूद है जैसे कि a =k * b + r।
ठीक इसी तरह a % b
a
. कॉलम में गैर-ऋणात्मक लाभांश के लिए काम करता है :
5 = 1 * 3 + 2
, इसलिए 5 और 3 का शेष 2
. के बराबर है ।
9 = 3 * 3 + 0
, इसलिए शेष 9 और 3 के बराबर 0
. है ।
5 = (-1) * (-3) + 2
, इसलिए 5 और -3 का शेष 2
. के बराबर है ।
स्पष्ट रूप से, एक त्रुटि दिखाई जाती है यदि भाजक b
है 0
, क्योंकि आप 0
. से विभाजित नहीं कर सकते ।
जब लाभांश a
. हो तो सही शेषफल प्राप्त करना समस्याग्रस्त होता है एक ऋणात्मक संख्या है। दुर्भाग्य से, a % b
a
. होने पर ऋणात्मक मान लौटा सकता है नकारात्मक है। उदा.:
-2 % 5
रिटर्न -2
इसे कब वापस करना चाहिए 3
।
-5 % -3
रिटर्न -2
इसे कब वापस करना चाहिए 1
।
समाधान 2 (सभी नंबरों के लिए सही):
SELECT a, b, CASE WHEN a % b >= 0 THEN a % b ELSE a % b + ABS(b) END AS remainder FROM numbers;
नतीजा यह है:
ए | <थ>बी <थ>शेष||
---|---|---|
9 | 3 | 0 |
5 | 3 | 2 |
2 | 3 | 2 |
0 | 3 | 0 |
-2 | 3 | 1 |
-5 | 3 | 1 |
-9 | 3 | 0 |
5 | -3 | 2 |
-5 | -3 | 1 |
5 | 0 | त्रुटि |
0 | 0 | त्रुटि |
चर्चा:
कोई भी . के विभाजन के शेष भाग की गणना करने के लिए दो पूर्णांक (ऋणात्मक या गैर-ऋणात्मक), आप CASE WHEN
. का उपयोग कर सकते हैं निर्माण। अगर a % b
गैर-ऋणात्मक है, शेष बस a % b
है . अन्यथा, हमें a % b
. द्वारा दिए गए परिणाम को ठीक करने की आवश्यकता है ।
अगर a % b
एक ऋणात्मक मान लौटाता है, आपको एक भाजक का निरपेक्ष मान a % b
. में जोड़ना चाहिए . यानी इसे a % b + ABS(b)
बनाएं :
-2 % 5
रिटर्न -2
इसे कब वापस करना चाहिए 3
. आप 5
. जोड़कर इसे ठीक कर सकते हैं ।
-5 % (-3)
रिटर्न -2
इसे कब वापस करना चाहिए 1
. आप 3
. जोड़कर इसे ठीक कर सकते हैं ।
जब a % b
एक ऋणात्मक मान देता है, CASE WHEN
परिणाम a % b + ABS(b)
होना चाहिए . इस तरह आपको समाधान 2 मिलता है। यदि आपको ABS()
. के बारे में एक पुनश्चर्या की आवश्यकता है फ़ंक्शन काम करता है, कुकबुक पर एक नज़र डालें SQL में एक निरपेक्ष मान की गणना कैसे करें।
बेशक, अगर b = 0
, आपको अभी भी एक त्रुटि मिलेगी।
समाधान 3 (सभी नंबरों के लिए सही):
SELECT a, b, a % b + ABS(b) * (1 - SIGN(a % b + 0.5)) / 2 AS remainder FROM numbers;
नतीजा यह है:
ए | <थ>बी <थ>शेष||
---|---|---|
9 | 3 | 0 |
5 | 3 | 2 |
2 | 3 | 2 |
0 | 3 | 0 |
-2 | 3 | 1 |
-5 | 3 | 1 |
-9 | 3 | 0 |
5 | -3 | 2 |
-5 | -3 | 1 |
5 | 0 | त्रुटि |
0 | 0 | त्रुटि |
चर्चा:
इस समस्या को हल करने का एक और तरीका है। CASE WHEN
. के बजाय , अधिक जटिल एक-पंक्ति वाले गणितीय सूत्र का उपयोग करें:
a % b + ABS(b) * (1 - SIGN(a % b + 0.5)) / 2
समाधान 2 में, a % b + ABS(b)
उन मामलों के लिए लौटाया गया था जब a % b < 0
. ध्यान दें कि a % b + ABS(b) = a % b + ABS(b) * 1 when a % b < 0
।
तो, हम ABS(b)
. को गुणा कर सकते हैं a % b
. के ऋणात्मक मानों के लिए 1 के बराबर व्यंजक द्वारा और 0
a % b
. के गैर-ऋणात्मक मानों के लिए . चूंकि a % b
हमेशा एक पूर्णांक होता है, व्यंजक a % b + 0.5
a % b >= 0
. के लिए हमेशा सकारात्मक होता है और a % b < 0
. के लिए ऋणात्मक . आप 1
. से कम किसी भी धनात्मक संख्या का उपयोग कर सकते हैं 0.5
. के बजाय ।
साइन फंक्शन SIGN()
रिटर्न 1
यदि इसका तर्क पूर्णतया सकारात्मक है, -1
अगर यह सख्ती से नकारात्मक है, और 0
अगर यह 0
. के बराबर है . हालांकि, आपको कुछ ऐसा चाहिए जो केवल 0
returns लौटाए और 1
, नहीं 1
और -1
. लेकिन कोई चिंता नहीं! यहां बताया गया है कि आप इसे कैसे ठीक करते हैं:
(1 - 1) / 2 = 0
(1 - (-1)) / 2 = 1
फिर, सही व्यंजक जिससे आपको गुणा करना चाहिए ABS(b)
है:
(1 - SIGN(a % b + 0.5)) / 2
तो, संपूर्ण सूत्र है:
a % b + ABS(b) * (1 - SIGN(a % b + 0.5)) / 2