जावा में जब आप करते हैं
a % b
यदि कोई ऋणात्मक है, तो उसे नकारात्मक परिणाम वापस करना होगा, बजाय इसके कि चारों ओर b को लपेटना चाहिए। इसे ठीक करने का सबसे अच्छा तरीका क्या है? केवल एक तरीका है जो मैं सोच सकता हूं
a < 0 ? b + a : a % b
जावा में जब आप करते हैं
a % b
यदि कोई ऋणात्मक है, तो उसे नकारात्मक परिणाम वापस करना होगा, बजाय इसके कि चारों ओर b को लपेटना चाहिए। इसे ठीक करने का सबसे अच्छा तरीका क्या है? केवल एक तरीका है जो मैं सोच सकता हूं
a < 0 ? b + a : a % b
जवाबों:
यह व्यवहार करता है क्योंकि इसे% b = a - a / b * b होना चाहिए; अर्थात यह शेष है।
आप कर सकते हैं (एक% b + b)% b
यह अभिव्यक्ति के परिणाम के रूप में काम करता है (a % b)
जरूरी तुलना में कम है b
, कोई फर्क नहीं पड़ता अगर a
सकारात्मक या नकारात्मक है। जोड़ना b
नकारात्मक मूल्यों का ध्यान रखता है a
, क्योंकि (a % b)
एक नकारात्मक मूल्य है -b
और 0
, (a % b + b)
आवश्यक रूप से कम b
और सकारात्मक है। पिछले मोडुलो के a
साथ शुरू होने के मामले में सकारात्मक था, अगर a
सकारात्मक है तो (a % b + b)
इससे बड़ा हो जाएगा b
। इसलिए, (a % b + b) % b
इसे b
फिर से छोटे में बदल देता है (और नकारात्मक a
मूल्यों को प्रभावित नहीं करता है )।
(a % b)
आवश्यक रूप से कम होता है b
(कोई फर्क नहीं पड़ता कि a
सकारात्मक या नकारात्मक है), जोड़ना b
नकारात्मक मूल्यों का ख्याल रखता है a
, चूंकि (a % b)
कम से कम है b
और तुलना में कम है 0
, (a % b + b)
आवश्यक रूप से कम b
और सकारात्मक है। पिछले मोडुलो के a
साथ शुरू होने के मामले में सकारात्मक था, अगर a
सकारात्मक है तो (a % b + b)
इससे बड़ा हो जाएगा b
। इसलिए, (a % b + b) % b
इसे b
फिर से छोटे में बदल देता है (और नकारात्मक a
मूल्यों को प्रभावित नहीं करता है )।
a < 0
, शायद आप एक नज़र डाल सकते हैं)
(a % b + b) % b
बहुत बड़े मूल्यों के लिए टूट जाता है a
और b
। उदाहरण के लिए, परिणाम के रूप में उपयोग करना a = Integer.MAX_VALUE - 1
और b = Integer.MAX_VALUE
देना होगा -3
, जो एक नकारात्मक संख्या है, जो कि आप बचना चाहते थे।
while
यदि आप वास्तव में इसकी आवश्यकता है सिवाय इसके कि आप if
वास्तव में तेजी से केवल एक मामले में जरूरत है, तो @Mikepote धीमा होगा ।
Java 8 के अनुसार, आप Math.floorMod (int x, int y) और Math.floorMod (long x, long y) का उपयोग कर सकते हैं । ये दोनों विधियां पीटर के जवाब के समान परिणाम देती हैं।
Math.floorMod( 2, 3) = 2
Math.floorMod(-2, 3) = 1
Math.floorMod( 2, -3) = -1
Math.floorMod(-2, -3) = -2
float
या double
तर्क के साथ काम नहीं करता है। मॉड बाइनरी ऑपरेटर ( %
) भी float
और double
ऑपरेंड के साथ काम करता है।
जावा 8 का उपयोग नहीं करने (या उपयोग करने में सक्षम नहीं) के लिए अभी तक, अमरूद 11.0 के बाद से उपलब्ध IntMath.mod () के साथ बचाव में आया था ।
IntMath.mod( 2, 3) = 2
IntMath.mod(-2, 3) = 1
एक चेतावनी: जावा 8 के Math.floorMod () के विपरीत, विभाजक (दूसरा पैरामीटर) नकारात्मक नहीं हो सकता।
संख्या सिद्धांत में, परिणाम हमेशा सकारात्मक होता है। मुझे लगता है कि यह हमेशा कंप्यूटर भाषाओं में ऐसा नहीं होता है क्योंकि सभी प्रोग्रामर गणितज्ञ नहीं होते हैं। मेरे दो सेंट, मैं इसे भाषा का डिज़ाइन दोष मानूंगा, लेकिन अब आप इसे बदल नहीं सकते।
= MOD (-4,180) = 176 = MOD (176, 180) = 176
क्योंकि 180 * (-1) + 176 = -4 180 * 0 + 176 = 176 के समान है
यहाँ घड़ी के उदाहरण का उपयोग करते हुए, http://mathworld.wolfram.com/Congruence.html आप अवधि_फॉल_टाइम मॉड साइकिल_-डायमेंशन -45 मिनट नहीं कहेंगे, आप 15 मिनट कहेंगे, भले ही दोनों उत्तर आधार समीकरण को संतुष्ट करते हों।
-1
बजाय चुनना n-1
) तो उस पर है।
जावा 8 में है Math.floorMod
, लेकिन यह बहुत धीमा है (इसके कार्यान्वयन में कई विभाजन, गुणा और एक सशर्त है)। यह संभव है कि जेवीएम के पास इसके लिए एक आंतरिक अनुकूलित स्टब है, जो इसे काफी गति देगा।
इसके बिना ऐसा करने का सबसे तेज़ तरीका floorMod
कुछ अन्य उत्तरों की तरह है, लेकिन बिना किसी सशर्त शाखाओं के और केवल एक धीमी गति से %
ऑप।
मान लेना सकारात्मक है, और x कुछ भी हो सकता है:
int remainder = (x % n); // may be negative if x is negative
//if remainder is negative, adds n, otherwise adds 0
return ((remainder >> 31) & n) + remainder;
जब परिणाम n = 3
:
x | result
----------
-4| 2
-3| 0
-2| 1
-1| 2
0| 0
1| 1
2| 2
3| 0
4| 1
यदि आपको सटीक मॉड ऑपरेटर के बीच केवल 0
और समान वितरण की आवश्यकता है n-1
, और आपका x
पास पास नहीं है 0
, तो निम्न और भी तेज़ होगा, क्योंकि अधिक अनुदेश स्तर समानता है और धीमी %
गणना अन्य के साथ समानांतर में होगी भागों के रूप में वे इसके परिणाम पर निर्भर नहीं करते हैं।
return ((x >> 31) & (n - 1)) + (x % n)
उपरोक्त के लिए परिणाम n = 3
:
x | result
----------
-5| 0
-4| 1
-3| 2
-2| 0
-1| 1
0| 0
1| 1
2| 2
3| 0
4| 1
5| 2
यदि इंट की पूरी रेंज में इनपुट यादृच्छिक है, तो दोनों समाधानों का वितरण समान होगा। यदि इनपुट शून्य के पास होता है, n - 1
तो बाद के समाधान में बहुत कम परिणाम होंगे ।
यहाँ एक विकल्प है:
a < 0 ? b-1 - (-a-1) % b : a % b
यह उस अन्य सूत्र [(एक% b + b)% b] से अधिक तेज़ हो भी सकता है और नहीं भी। अन्य सूत्र के विपरीत, इसमें एक शाखा होती है, लेकिन एक कम मोडुलो ऑपरेशन का उपयोग करता है। शायद एक जीत अगर कंप्यूटर एक <0 का सही अनुमान लगा सकता है।
(संपादित करें: सूत्र फिक्स्ड।)