जावा नकारात्मक संख्याओं के साथ मापांक की गणना कैसे करता है?


92

क्या मैं मापांक गलत कर रहा हूँ? क्योंकि जावा -13 % 64में मूल्यांकन करना है, -13लेकिन मुझे मिलता है 51


102
@ एक स्थिर मुख्य शून्य के बिना भी ... मुझे कोड दिखाई देता है।
जोरिस मेय्स

22
मुझे
I१३

7
कैसे यह आप -13 से 51 ratehr हो रही है है।
रायडवल

3
आप बिल्कुल भी मापांक नहीं कर रहे हैं। जावा में कोई मॉडुलो ऑपरेटर नहीं है। %एक शेष ऑपरेटर है।
को Lorne

3
भ्रामक प्रश्न: जावा 8 देता है -13, जैसा कि कुछ अन्य लोग कहते हैं। आपको किस जावा संस्करण के साथ माना जाता है?
Jan 13ankowski

जवाबों:


104

ऋणात्मक संख्याओं के मापांक की दोनों परिभाषाएँ उपयोग में हैं - कुछ भाषाएँ एक परिभाषा और कुछ अन्य का उपयोग करती हैं।

यदि आप नकारात्मक इनपुट के लिए ऋणात्मक संख्या प्राप्त करना चाहते हैं तो आप इसका उपयोग कर सकते हैं:

int r = x % n;
if (r > 0 && x < 0)
{
    r -= n;
}

इसी तरह यदि आप एक ऐसी भाषा का उपयोग कर रहे हैं जो नकारात्मक इनपुट पर ऋणात्मक संख्या देता है और आप सकारात्मक पसंद करेंगे:

int r = x % n;
if (r < 0)
{
    r += n;
}

3
यह अच्छा नहीं है अगर n नकारात्मक है। यदि आप जावा 7 लैंग स्पेक (धारा 15.17.3): (-5)% (-3) = -2 से एक ही उदाहरण देते हैं। -3 जोड़ने से काम नहीं चलेगा। यदि आप सुनिश्चित करना चाहते हैं कि मूल्य सकारात्मक है तो आपको n का पूर्ण मूल्य जोड़ना चाहिए।
पार्टलोव

6
जावा में नकारात्मक मोड्यूलो कुछ भी नहीं बदलता है, अगर आप किसी भी तरह से ABS () का उपयोग करते हैं, तो बस r = x% abs (n) लिखें। अगर मुझे बयान पसंद नहीं है, तो मैं r = ((x% n) + n)% n लिखूंगा। 2 मोडुलो (2,4,8,16, आदि ..) और सकारात्मक जवाब की शक्ति के बारे में, बाइनरी मास्क आर =
एक्सएंड

3
जावा (प्रश्न टैग के अनुसार) के संदर्भ में यह उत्तर अनिवार्य रूप से "गलत" है। अभिव्यक्ति को देखते हुए x % y, A) यदि xऋणात्मक है तो शेष ऋणात्मक है, अर्थात x % y == -(-x % y)। बी) के हस्ताक्षर yकोई प्रभाव नहीं अर्थातx % y == x % -y
बोहेमियन

71

"गणितीय रूप से" दोनों सही हैं:

-13 % 64 = -13 (on modulus 64)  
-13 % 64 = 51 (on modulus 64)

विकल्पों में से एक को जावा भाषा डेवलपर्स द्वारा चुना जाना था और उन्होंने चुना:

परिणाम का संकेत लाभांश के संकेत के बराबर होता है।

इसे जावा स्पेक्स में कहते हैं:

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3


8
सवाल यह है कि " -13 % 64 = 51जब मैं उम्मीद कर रहा था तो जावा मुझे क्यों देता है -13?"।
पास्कल कूउक

5
@ पास्कल: जावा आपको गणित में सही परिभाषा देता है और जिस तरह से इसे लागू किया गया है कि आप इससे उम्मीद नहीं करते हैं।

9
गणितीय रूप से समझदार व्यवहार जावा 8 में उपलब्ध है: Math.floorMod
जेसी ग्लिक

1
उनके 15.17.3 में कुछ शेष संचालक% उदाहरण स्पष्ट नहीं है। int result = (-5) % 3;-2 देता है। int result = (-3) % 5;-3 देता है। सामान्य तौर पर, int result = (-a) % b;सही उत्तर देता है जब | -ए | > बी। जब उचित परिणाम प्राप्त करने के लिए | <b हमें विभाजक को लपेटना चाहिए। int result = ((-a) % b) + b;नकारात्मक के लिए एक या int result = (((-a) % b) + b) % b;सकारात्मक या नकारात्मक के लिए एक
ओज़ एड्री

@ मैं यह समझ नहीं पाया, दोनों एक ही कैसे हो सकते हैं?
किशोर कुमार कोरडा

20

क्या आप वाकई जावा में काम कर रहे हैं? जावा जावा -13% 64 = -13 उम्मीद के मुताबिक देता है। लाभांश का संकेत!


15

आपका परिणाम जावा के लिए गलत है। कृपया कुछ संदर्भ प्रदान करें कि आप इस पर कैसे पहुंचे (आपका कार्यक्रम, कार्यान्वयन और जावा का संस्करण)।

से जावा भाषा विशिष्टता

15.17.3 रेमिनेटर ऑपरेटर%
[...]
बाइनरी न्यूमेरिक प्रमोशन (produces5.6.2) के बाद पूर्णांक वाले ऑपरेंड के लिए शेष संचालन परिणाम मान उत्पन्न करता है जैसे (a / b) * b + (a% b) बराबर होता है ए।
15.17.2 डिवीजन ऑपरेटर /
[...]
पूर्णांक विभाजन 0 की ओर गोल होता है।

चूँकि / शून्य की ओर गोल है (शून्य में जिसके परिणामस्वरूप), इस मामले में% का परिणाम नकारात्मक होना चाहिए।


उनके 15.17.3 में कुछ शेष संचालक% उदाहरण स्पष्ट नहीं है। int result = (-5) % 3;-2 int result = (-3) % 5;देता है -3 सामान्य रूप से, int result = (-a) % b;सही उत्तर देता है जब -a | > b उचित परिणाम प्राप्त करने के लिए जब -a | <b हमें विभाजक को लपेटना चाहिए। int result = ((-a) % b) + b;नकारात्मक के लिए या int result = (((-a) % b) + b) % b;सकारात्मक या नकारात्मक के लिए एक।
ओज एड्री

1
आपकी टिप्पणी काफी अस्पष्ट है। अनुभाग सही परिणाम को परिभाषित करता है, और उदाहरण उस परिभाषा से सहमत हैं। आपके उदाहरण (-3) % 5के लिए परिभाषा के अनुसार सही परिणाम है -3, और जावा का एक सही कार्यान्वयन उस परिणाम का उत्पादन करना चाहिए।
starblue

मुझे लगता है कि मैंने खुद को सही ढंग से नहीं समझाया। जब मुझे "सही उत्तर" का मतलब कब | -a | <b होता है, तो एक सकारात्मक परिणाम प्राप्त करने के लिए हमें b को जोड़कर% b से दिए गए परिणाम को "लपेटना" चाहिए। मेरे उदाहरण में, (-3)%5वास्तव में देता है -3, और यदि हम चाहते हैं कि सकारात्मक शेष हम इसमें 5 जोड़ दें, और फिर परिणाम होगा2
Oz Edri

6

आप उपयोग कर सकते हैं

(x % n) - (x < 0 ? n : 0);

3
@ruslik आप भी कर सकते हैं ((x % k) + k) % k:। (हालांकि आपका शायद अधिक पठनीय है।)
जॉन कुर्लाक

2
@JohnKurlak आप संस्करण इस तरह से काम करता है: 4% 3 = 1 या 4% -3 = -2 या -4% 3 = 2 या -4% -3 = -1 लेकिन रुस्लिक से इस तरह काम करता है: 4% 3 = 1 या 4% -3 = 1 या -4% 3 = -4 या -4% -3 = 2
जोशुआ

1
@ जोशुआ यह इंगित करने के लिए धन्यवाद। जब आप चाहते हैं कि मेरा कोड [0, sign(divisor) * divisor)इसके बजाय की सीमा में मापांक परिणाम के लिए उपयोगी है [0, sign(dividend) * divisor)
जॉन कुर्लाक

3

आपका उत्तर विकिपीडिया में है: मोडुलो ऑपरेशन

यह कहता है, कि Java में modulo Operation पर साइन डिविडेंड की तरह ही होता है। और जब से हम बाकी डिवीजन ऑपरेशन के बारे में बात कर रहे हैं, यह ठीक है, कि यह आपके मामले में -13 लौटा देता है, -13/64 = 0. -13-0 = -13 के बाद से।

संपादित करें: क्षमा करें, आपके प्रश्न को गलत समझा ... आप सही हैं, जावा को -13 देना चाहिए। क्या आप अधिक आस-पास कोड प्रदान कर सकते हैं?


2

नकारात्मक ऑपरेंड के साथ मोडुलो अंकगणित भाषा डिजाइनर द्वारा परिभाषित किया गया है, जो इसे भाषा के कार्यान्वयन के लिए छोड़ सकता है, जो सीपीयू वास्तुकला की परिभाषा को स्थगित कर सकता है।

मैं जावा भाषा की परिभाषा नहीं खोज पाया।
थैंक्स ईशर, जावा भाषा विनिर्देशन के लिए रेमिनेटर ऑपरेटर% का कहना है कि परिणाम का संकेत अंश के संकेत के समान है।


1

इसे दूर करने के लिए, आप 64सकारात्मक मान तक नकारात्मक मूल्य तक (या जो भी आपका मापांक आधार है) जोड़ सकते हैं

int k = -13;
int modbase = 64;

while (k < 0) {
    k += modbase;
}

int result = k % modbase;

परिणाम अभी भी उसी तुल्यता वर्ग में होगा।


1

x = x + m = x - mमापांक में m
इसलिए -13 = -13 + 64मापांक में 64 और -13 = 51मापांक में 64
मान लें Z = X * d + r, यदि 0 < r < Xतब विभाजन में Z/Xहम rशेष को कहते हैं ।
Z % Xशेष बचता है Z/X


1

मॉड फ़ंक्शन को उस राशि के रूप में परिभाषित किया जाता है जिसके द्वारा एक संख्या विभाजक के सबसे बड़े पूर्णांक से अधिक होती है जो उस संख्या से अधिक नहीं होती है। तो आपके मामले में

-13 % 64

64 का सबसे बड़ा पूर्णांक एकाधिक -13 से अधिक नहीं है -64 है। अब -64 से -13 घटाते समय यह 51 के बराबर हो जाता है-13 - (-64) = -13 + 64 = 51


0

जावा के मेरे संस्करण में JDK 1.8.0_05 -13% 64 = -13

आप -13- (int (-13/64)) को दूसरे शब्दों में विभाजित करने के लिए एक पूर्णांक के लिए डिवीजन कास्ट कर सकते हैं ताकि अंश से घटाया जा सके इसलिए अंश - (int (अंश / हर)) सही देना चाहिए शेष और संकेत


0

जावा नवीनतम संस्करणों में आपको मिलता है -13%64 = -13। उत्तर में हमेशा अंश का चिह्न होगा।


यह परिवर्तन किस संस्करण में किया गया था?
नाइटशेडक्यूवेन

जावा 7 में स्पष्ट रूप से उल्लेख किया गया है कि मॉड में अंश का चिन्ह होगा :)
vsn harish rayasam

@NightShadeQueen इसे कभी नहीं बदला गया।
लोर्ने की

0

जेएलएस की धारा 15.17.3 के अनुसार, "बाइनरी न्यूमेरिक प्रमोशन के बाद पूर्णांक वाले ऑपरेशंस के लिए शेष संचालन एक परिणाम मान उत्पन्न करता है जैसे (ए / बी) * बी + (एक% बी) एक के बराबर है। यह पहचान भी रखती है। विशेष मामले में कि लाभांश अपने प्रकार के लिए सबसे बड़ा संभव परिमाण का ऋणात्मक पूर्णांक है और भाजक -1 है (शेष 0 है)। "

उम्मीद है की वो मदद करदे।


-1

मुझे नहीं लगता कि जावा इस मामले में 51 रिटर्न करता है। मैं एक मैक पर जावा 8 चला रहा हूं और मुझे मिल रहा है:

-13 % 64 = -13

कार्यक्रम:

public class Test {
    public static void main(String[] args) {
        int i = -13;
        int j = 64;
        System.out.println(i % j);
    }
}

5
@XaverKapeller, नहीं! कई लोगों ने बताया कि गणितीय रूप से बोलना -13 और 51 सही हैं। जावा में, -13 अपेक्षित उत्तर है, और यह वही है जो मुझे भी मिला है, इसलिए मुझे नहीं पता कि कैसे सबमिटटर 51 मिला, यह रहस्य है। संदर्भ के बारे में मोड विवरण इस प्रश्न का सही उत्तर देने में मदद कर सकता है।
फेबिन

@Xaver कपलर: 51 और -13 दोनों कैसे सही हो सकते हैं? जावा केवल एक मान
लौटाएगा

@XaverKapeller एक उत्तर कैसे हो सकता है कि जावा वास्तव में गलत क्या करता है?
लोर्ने का मार्क्विस

@ ईजेपी मुझे लगता है कि 3 साल पहले जब मैंने यह लिखा था कि मैं गणितीय सटीकता को महत्व देने के लिए पर्याप्त गूंगा था कि जावा इस से कैसे निपटता है। मेरी बेवकूफी भरी टिप्पणी को दूर करने के लिए मुझे याद दिलाने के लिए धन्यवाद: D
Xaver Kapeller
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.