दिलचस्प पोस्ट
स्ट्रिंग दिनांक को java.sql.Date में परिवर्तित करें क्या जावा में रचनाकार से सार पद्धति को कॉल करना ठीक है? AngularJS का उपयोग करते हुए नई विंडो में लिंक खोलें फ़्लोटिंग पॉइंट संख्या गलत क्यों हैं? कैसे TensorFlow में एक Tensor वस्तु के मूल्य को मुद्रित करने के लिए? मैं कोणीय 2 में सिंगलटन सेवा कैसे बनाऊं? सी # – रिअलटाइम कंसोल आउटपुट रीडायरेक्शन जावा एपीआई कम या बाइट के बजाय int क्यों उपयोग करता है? एसडीके 21 के नीचे नोक्लेस डीफफाउंड एरर सीएसएस 2 चयनकर्ताओं का उपयोग करते हुए मैं एक तत्व का nth बच्चा कैसे प्राप्त करूं? जावा में दिनांक ऑब्जेक्ट से एक्स दिन कैसे घटाना है? फ़ंक्शन पॉइंटर के रूप में लैम्ब्डा पास करना बिग एंडियन के लिए लिटिल एंडियन कन्वर्ट सीएसएस के साथ एरो बॉक्स वसंत MVC: कस्टम 404 त्रुटि पृष्ठों को वापस कैसे करें?

C / C ++ / Obj-C में एक मॉड्यूलो (%) ऑपरेटर को कोड कैसे करें जो नकारात्मक संख्या संभालता है

सी-व्युत्पन्न भाषाओं (एक गणितज्ञ के रूप में) के मेरे पालतू जानवरों में से एक यह है कि

(-1) % 8 // comes out as -1, and not 7 fmodf(-1,8) // fails similarly 

सबसे अच्छा समाधान क्या है?

सी ++ टेम्पलेट्स और ऑपरेटर ओवरलोडिंग की संभावना की अनुमति देता है, लेकिन इनमें से दोनों मेरे लिए जलते हुए पानी हैं उदाहरणों के कृतज्ञता से प्राप्त

Solutions Collecting From Web of "C / C ++ / Obj-C में एक मॉड्यूलो (%) ऑपरेटर को कोड कैसे करें जो नकारात्मक संख्या संभालता है"

सबसे पहले मैं यह जानना चाहूंगा कि आप इस तथ्य पर भरोसा भी नहीं कर सकते कि (-1) % 8 == -1 आप जिस चीज़ पर भरोसा कर सकते हैं, वह है (x / y) * y + ( x % y) == x हालांकि शेष राशि नकारात्मक है या नहीं, कार्यान्वयन-परिभाषित है

अब यहां टेम्प्लेट का उपयोग क्यों किया जाता है? इनट्स और लॉन्ड्स के लिए एक ओवरलोड करना होगा

 int mod (int a, int b) { int ret = a % b; if(ret < 0) ret+=b; return ret; } 

और अब आप इसे mod (-1,8) जैसे कॉल कर सकते हैं और यह 7 के रूप में दिखाई देगा।

संपादित करें: मुझे अपने कोड में एक बग मिला यह काम नहीं करेगा यदि b नकारात्मक है तो मुझे लगता है कि यह बेहतर है:

 int mod (int a, int b) { if(b < 0) //you can check for b == 0 separately and do what you want return mod(a, -b); int ret = a % b; if(ret < 0) ret+=b; return ret; } 

संदर्भ: सी +03 पैराग्राफ 5.6 खंड 4:

द्विआधारी / ऑपरेटर भागफल का उत्पादन करते हैं, और द्विआधारी% ऑपरेटर दूसरे द्वारा पहली अभिव्यक्ति के विभाजन से शेष पैदा करते हैं। यदि / या% का दूसरा ऑपरेशन शून्य है, तो व्यवहार अनिर्धारित है; अन्यथा (ए / बी) * बी + ए% बी एक के बराबर है। यदि दोनों ऑपरैक्स अबाधित हैं तो शेष गैर-नकारात्मक है; यदि नहीं, तो बाकी का चिन्ह कार्यान्वयन-परिभाषित है

यहाँ सी फ़ंक्शन है जो दोनों ओर से सकारात्मक या नकारात्मक पूर्णांक या आंशिक मानों को नियंत्रित करता है

 #include <math.h> float mod(float a, float N) {return a - N*floor(a/N);} //return in range [0, N) 

यह निश्चित रूप से गणितीय दृष्टिकोण से सबसे खूबसूरत समाधान है। हालांकि, मुझे यकीन नहीं है कि यह पूर्णांक को संभालने में मजबूत है। कभी-कभी फ़्लोटिंग प्वाइंट त्रुटियों को जब में अंतर परिवर्तित होता है -> एफपी -> इंट

मैं गैर कोड के लिए इस कोड का उपयोग कर रहा हूँ, और int के लिए एक अलग फ़ंक्शन।

नोट: N = 0 जाल करने की आवश्यकता है!

परीक्षक कोड:

 #include <math.h> float mod(float a, float N) { float ret = a - N * floor (a / N); printf("%f.1 mod %f.1 = %f.1 \n", a, N, ret); return ret; } int main (char* argc, char** argv) { printf ("fmodf(-10.2, 2.0) = %f.1 == FAIL! \n\n", x); float x; x = mod(10.2f, 2.0f); x = mod(10.2f, -2.0f); x = mod(-10.2f, 2.0f); x = mod(-10.2f, -2.0f); return 0; } 

(नोट: आप इसे सीधे कोडपैड से संकलित और चला सकते हैं: http://codepad.org/UOgEqAMA )

आउटपुट:

एफएमओडीएफ (-10.2, 2.0) = -0.20 == असफल!

10.2 mod 2.0 = 0.2
10.2 आधुनिक -2.0 = -1.8
-10.2 मोड 2.0 = 1.8
-10.2 मोड -2.0 = -0.2

मैंने अभी देखा है कि बर्जने स्ट्रावस्ट्रुप लेबल को % ऑपरेटर के रूप में लेता है, कि मॉड्यूलो ऑपरेटर।

मैं शर्त लगा सकता हूं कि यह एएनएसआई सी और सी ++ विनिर्देशों में इसका औपचारिक नाम है, और शब्दावली का दुरुपयोग हुआ है। क्या किसी को भी इस तथ्य के लिए पता है?

लेकिन अगर यह मामला है तो सी के एफएमओडीएफ () फ़ंक्शन (और संभवत: अन्य) बहुत भ्रामक हैं। उन्हें एफ्रैफ़ (), आदि लेबल करना चाहिए

पूर्णांक के लिए यह सरल है बस करो

 (((x < 0) ? ((x % N) + N) : x) % N) 

जहां मुझे लगता है कि N सकारात्मक और x के प्रकार में प्रतिनिधित्व योग्य है। आपका पसंदीदा संकलक इसे अनुकूलित करने में सक्षम होना चाहिए, जैसे कि यह कोडांतरक में केवल एक मोड ऑपरेशन में समाप्त होता है।

एक गणितज्ञ के लिए सबसे अच्छा समाधान है पायथन का उपयोग करना

C ++ ऑपरेटर ओवरलोडिंग इसके साथ कुछ नहीं करना है। आप अंतर्निहित प्रकारों के लिए ऑपरेटर अधिभार नहीं कर सकते। आप क्या चाहते हैं केवल एक फ़ंक्शन है बेशक आप सी ++ टेम्पलेटिंग का इस्तेमाल उस कोड को सिर्फ 1 टुकड़ा के साथ सभी प्रासंगिक प्रकार के लिए लागू कर सकते हैं।

मानक सी लाइब्रेरी fmod प्रदान करती है, अगर मुझे अस्थायी बिंदु प्रकारों के लिए नाम ठीक से याद आता है।

पूर्णांक के लिए आप एक C ++ फ़ंक्शन टेम्पलेट परिभाषित कर सकते हैं जो हमेशा गैर-नकारात्मक शेष (यूक्लिडियन डिवीजन से संबंधित) देता है …

 #include <stdlib.h> // abs template< class Integer > auto mod( Integer a, Integer b ) -> Integer { Integer const r = a%b; return (r < 0? r + abs( b ) : r); } 

… और बस a%b बजाय mod(a, b) लिखें

यहां प्रकार Integer को हस्ताक्षरित पूर्णांक प्रकार की आवश्यकता है।

यदि आप सामान्य गणित व्यवहार चाहते हैं, जहां शेष का चिन्ह भाजक के चिन्ह के समान है, तो आप ऐसा कर सकते हैं

 template< class Integer > auto floor_div( Integer const a, Integer const b ) -> Integer { bool const a_is_negative = (a < 0); bool const b_is_negative = (b < 0); bool const change_sign = (a_is_negative != b_is_negative); Integer const abs_b = abs( b ); Integer const abs_a_plus = abs( a ) + (change_sign? abs_b - 1 : 0); Integer const quot = abs_a_plus / abs_b; return (change_sign? -quot : quot); } template< class Integer > auto floor_mod( Integer const a, Integer const b ) -> Integer { return a - b*floor_div( a, b ); } 

Integer पर एक ही बाधा के साथ, यह एक हस्ताक्षरित प्रकार है


¹ क्योंकि पायथन का पूर्णांक विभाजन नकारात्मक अनन्तता के लिए गोल करता है।

ओह, मैं इसके लिए भी% डिजाइन से नफरत करता हूं ….

आप लाभांश को अहस्ताक्षरित तरीके से बदल सकते हैं जैसे:

 unsigned int offset = (-INT_MIN) - (-INT_MIN)%divider result = (offset + dividend) % divider 

जहां ऑफ़सेट मॉड्यूल के (- INT_MIN) बहुमूल्य है, इसलिए इसे जोड़ना और घटाना मॉड्यूलो नहीं बदलेगा ध्यान दें कि यह अहस्ताक्षरित प्रकार है और परिणाम पूर्णांक होगा। दुर्भाग्य से यह मान सही रूप से INT_MIN परिवर्तित नहीं कर सकता … (- ऑफसेट-1) के रूप में वे arifmetic अतिप्रवाह के कारण लेकिन इस पद्धति में केवल एक अतिरिक्त अंकगणितीय प्रति ऑपरेशन (और कोई शर्त नहीं) का सुझाव है जब निरंतर विभक्त के साथ काम करना है, इसलिए यह डीएसपी-जैसे अनुप्रयोगों में प्रयोग करने योग्य है।

विशेष मामले हैं, जहां विभक्त 2 एन (दो की पूर्णांक शक्ति) है, जिसके लिए मॉड्यूल का गणित सरल गणित और बिट्योर तर्क के रूप में गणना किया जा सकता है।

 dividend&(divider-1) 

उदाहरण के लिए

 x mod 2 = x & 1 x mod 4 = x & 3 x mod 8 = x & 7 x mod 16 = x & 15 

इस फ़ंक्शन का उपयोग करके मॉड्यूलो प्राप्त करना अधिक सामान्य और कम मुश्किल तरीका है (केवल सकारात्मक विभक्त के साथ काम करता है):

 int mod(int x, int y) { int r = x%y; return r<0?r+y:r; } 

यह सिर्फ सही परिणाम अगर यह ऋणात्मक है

इसके अलावा आप चाल भी सकते हैं:

(पी% क्यू + क्यू)% क्यू

यह बहुत कम है लेकिन दो% का उपयोग करें- जो आमतौर पर धीमे हैं

मेरा मानना ​​है कि इस समस्या का एक और समाधान int के बजाय प्रकार के चर के लिए उपयोग किया जाएगा I

मैं सिर्फ कुछ कोड पर काम कर रहा था जहां% ऑपरेटर एक नकारात्मक मान वापस कर रहा था जिसके कारण कुछ मुद्दे ([0,1] पर एक समान यादृच्छिक चर उत्पन्न करने के लिए आप वास्तव में नकारात्मक संख्या नहीं चाहते हैं :)), लेकिन चर को स्विच करने के बाद लंबे समय तक टाइप करें, सबकुछ सुचारू रूप से चल रहा था और परिणाम मुझे अजगर में एक ही कोड चलाते समय मिल रहा था (मेरे लिए महत्वपूर्ण है क्योंकि मैं कई प्लेटफार्मों में समान "यादृच्छिक" नंबर उत्पन्न करने में सक्षम होना चाहता था

 / * चेतावनी: मैक्रो मॉड उसके तर्कों का दुष्प्रभाव कई बार मूल्यांकन करता है  * /
 #define mod (r, m) (((r)% (m)) + ((r) <0)? (मी): 0)

… या तुल्यता वर्ग के लिए किसी भी प्रतिनिधि को प्राप्त करने के लिए उपयोग किया जाता है

यहां एक पुराना प्रश्न का नया जवाब दिया गया है, जिसमें इस Microsoft अनुसंधान पत्र और उसके संदर्भों पर आधारित है।

ध्यान दें कि C11 और C ++ 11 के बाद से, div की शब्दावली शून्य के रूप में छिद्रण हो गई है (देखें [expr.mul]/4 )। इसके अलावा, D लिए D विभाजित, सी ++ 11 भागफल qT और शेष rT बारे में निम्नलिखित की गारंटी देता है

 auto const qT = D / d; auto const rT = D % d; assert(D == d * qT + rT); assert(abs(rT) < abs(d)); assert(signum(rT) == signum(D)); 

जहां 1, 0, +1 के लिए signum नक्शे, इसकी तर्क के आधार पर है कि क्या इसका तर्क <, ==,> 0 से (स्रोत कोड के लिए यह क्यू एंड ए देखें) पर निर्भर करता है।

कटौती किए गए विभाजन के साथ, बाकी का चिन्ह लाभांश D के चिन्ह के बराबर है , अर्थात -1 % 8 == -1 । C ++ 11 भी एक std::div फ़ंक्शन प्रदान करता है जो truncated विभाजन के अनुसार सदस्यों को quot और री के साथ एक स्ट्रिंग देता है।

अन्य परिभाषाएं भी संभव हैं, उदाहरण के लिए तथाकथित फर्श वाले डिवीजन को बिल्टिन कटौती वाले विभाजन के संदर्भ में परिभाषित किया जा सकता है

 auto const I = signum(rT) == -signum(d) ? 1 : 0; auto const qF = qT - I; auto const rF = rT + I * d; assert(D == d * qF + rF); assert(abs(rF) < abs(d)); assert(signum(rF) == signum(d)); 

फर्श वाले विभाजन के साथ, शेष का चिन्ह भाजक के संकेत के बराबर होता है । हस्सेल और ओबबेन जैसी भाषाओं में, फर्श वाले डिवीजन के लिए बिल्टिन ऑपरेटर्स हैं। सी ++ में, आपको उपरोक्त परिभाषाओं का उपयोग करते हुए एक फ़ंक्शन लिखना होगा।

फिर भी एक और तरीका है यूक्लिडियन डिवीजन , जिसे बिल्टिन कटौती वाले विभाजन के संदर्भ में भी परिभाषित किया जा सकता है

 auto const I = rT >= 0 ? 0 : (d > 0 ? 1 : -1); auto const qE = qT - I; auto const rE = rT + I * d; assert(D == d * qE + rE); assert(abs(rE) < abs(d)); assert(signum(rE) != -1); 

यूक्लिडियन डिवीजन के साथ, बाकी का चिन्ह हमेशा सकारात्मक होता है

सकारात्मक मॉड्यूल को खोजने के लिए सरल सामान्य कार्य होगा- यह एक्स के दोनों सकारात्मक और नकारात्मक मूल्यों पर काम करेगा।

 int modulo(int x,int N){ return (x % N + N) %N; } 

सी ++ के लिए उदाहरण टेम्पलेट

 template< class T > T mod( T a, T b ) { T const r = a%b; return ((r!=0)&&((r^b)<0) ? r + b : r); } 

इस टेम्प्लेट के साथ, शेष शेष का सी + + व्यवहार या लाभांश के समान संकेत होने के बजाय, शेष शेष शून्य या शून्य हो सकता है (विभाजक (नकारात्मक) (नकारात्मक अनन्तता की ओर गोल के समतुल्य) के समान चिह्न अंश) (शून्य के गोलाकार के बराबर)

 define MOD(a, b) ((((a)%(b))+(b))%(b)) 
 unsigned mod(int a, unsigned b) { return (a >= 0 ? a % b : b - (-a) % b); } 

यह समाधान (जब mod सकारात्मक है तब उपयोग के लिए) नकारात्मक विभाजन या शेष कार्यों को एकसाथ लेने से बचा जाता है:

 int core_modulus(int val, int mod) { if(val>=0) return val % mod; else return val + mod * ((mod - val - 1)/mod); } 

मुझे क्या करना होगा:

 ((-1)+8) % 8 

यह मॉड्यूलो को 7 देने के पहले के रूप में वांछित के रूप में पहले नंबर को जोड़ता है यह किसी भी संख्या के लिए -8 तक काम करना चाहिए -9 के लिए 2 * 8 जोड़ें