समस्या:
आप (गैर-ऋणात्मक) शेष खोजना चाहते हैं।
उदाहरण:
तालिका में 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, MOD(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 . उदा.:
5 = 1 * 3 + 2
, इसलिए 5 और 3 का शेष 2
. के बराबर है ।
9 = 3 * 3 + 0
, इसलिए शेष 9 और 3 के बराबर 0
. है ।
5 = (-1) * (-3) + 2
, इसलिए 5 और -3 का शेष 2
. के बराबर है ।
इस प्रकार MOD(a, b)
a
. कॉलम में गैर-ऋणात्मक लाभांश के लिए काम करता है . स्पष्ट रूप से, एक त्रुटि दिखाई जाती है यदि भाजक b
है 0
, क्योंकि आप 0
. से विभाजित नहीं कर सकते ।
जब लाभांश a ऋणात्मक संख्या हो तो सही शेषफल प्राप्त करना समस्याग्रस्त होता है। दुर्भाग्य से, MOD(a, b)
ऋणात्मक होने पर ऋणात्मक मान लौटा सकता है। उदा.:
MOD(-2, 5)
रिटर्न -2
इसे कब वापस करना चाहिए 3
।
MOD(-5, -3)
रिटर्न -2
इसे कब वापस करना चाहिए 1
।
समाधान 2 (सभी नंबरों के लिए सही):
SELECT a, b, CASE WHEN MOD(a, b) >= 0 THEN MOD(a, b) ELSE MOD(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
. का उपयोग कर सकते हैं निर्माण। जब MOD(a, b)
गैर-ऋणात्मक है, शेष बस MOD(a, b)
. है . अन्यथा, हमें MOD(a, b)
. द्वारा दिए गए परिणाम को ठीक करना होगा ।
MOD()
. होने पर आपको सही शेषफल कैसे मिलता है? एक नकारात्मक मूल्य देता है? आपको भाजक का निरपेक्ष मान MOD(a, b)
. में जोड़ना चाहिए . यानी इसे MOD(a, b) + ABS(b)
बनाएं :
MOD(-2, 5)
रिटर्न -2
इसे कब वापस करना चाहिए 3
. आप 5
. जोड़कर इसे ठीक कर सकते हैं ।
MOD(-5, -3)
रिटर्न -2
इसे कब वापस करना चाहिए 1
. आप 3
. जोड़कर इसे ठीक कर सकते हैं ।
जब MOD(a, b)
एक ऋणात्मक संख्या देता है, CASE WHEN
परिणाम MOD(a, b) + ABS(b)
. होना चाहिए . इस तरह से हम समाधान 2 प्राप्त करते हैं। यदि आपको ABS()
. के बारे में एक पुनश्चर्या की आवश्यकता है फ़ंक्शन काम करता है, कुकबुक पर एक नज़र डालें SQL में एक निरपेक्ष मान की गणना कैसे करें।
बेशक, आप अभी भी किसी भी संख्या को 0
. से विभाजित नहीं कर सकते हैं . तो, अगर b = 0
, आपको एक त्रुटि मिलेगी।
समाधान 3 (सभी नंबरों के लिए सही):
SELECT a, b, MOD(a, b) + ABS(b) * (1 - SIGN(MOD(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
. के बजाय , अधिक जटिल एक-पंक्ति वाले गणितीय सूत्र का उपयोग करें:
MOD(a, b) + ABS(b) * (1 - SIGN(MOD(a, b) + 0.5)) / 2
समाधान 2 में, MOD(a, b) + ABS(b)
मामलों के लिए वापस किया गया था जब MOD(a, b) < 0
. ध्यान दें कि MOD(a, b) + ABS(b) = MOD(a, b) + ABS(b) * 1 when MOD(a, b) < 0
।
इसके विपरीत, आप MOD(a, b)
return लौटाते हैं जब MOD(a, b) >= 0
. ध्यान दें कि MOD(a, b) = MOD(a, b) + ABS(b) * 0 when MOD(a, b) >= 0
।
तो, हम ABS(b)
. को गुणा कर सकते हैं एक नकारात्मक MOD(a, b)
. के लिए 1 के बराबर एक व्यंजक द्वारा और 0
एक गैर-नकारात्मक MOD(a, b)
. के लिए . चूंकि MOD(a, b)
हमेशा एक पूर्णांक होता है, व्यंजक MOD(a, b) + 0.5
MOD(a, b) ≥ 0
. के लिए हमेशा सकारात्मक होता है और MOD(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(MOD(a, b) + 0.5)) / 2
तो, संपूर्ण सूत्र है:
MOD(a, b) + ABS(b) * (1 - SIGN(MOD(a, b) + 0.5)) / 2