में मॉड्यूलस ऑपरेटर के साथ हस्ताक्षरित ओवरफ़्लो मैंने कुछ सी कोड में एक बग का सामना किया, और जब इसे ठीक करने में अपेक्षाकृत आसान था, तो मैं इसे बेहतर तरीके से समझने में सक्षम होना चाहता हूं। अनिवार्य रूप से क्या हुआ है कि मेरे पास दो हस्ताक्षरित पूर्णांक (uint32_t, वास्तव में) थे, जब मॉड्यूलस ऑपरेशन लागू किया गया था, तो एक नकारात्मक संख्या के हस्ताक्षरित समकक्ष, एक संख्या जो लपेटा गया था और इस प्रकार "बड़ा" था।सी
#include <stdio.h>
#include <stdint.h>
int main(int argc, char* argv[]) {
uint32_t foo = -1;
uint32_t u = 2048;
uint64_t ul = 2048;
fprintf(stderr, "%d\n", foo);
fprintf(stderr, "%u\n", foo);
fprintf(stderr, "%lu\n", ((foo * 2600000000) % u));
fprintf(stderr, "%ld\n", ((foo * 2600000000) % u));
fprintf(stderr, "%lu\n", ((foo * 2600000000) % ul));
fprintf(stderr, "%lu\n", foo % ul);
return 0;
}
इस, निम्नलिखित उत्पादन का उत्पादन मेरी x86_64 मशीन पर: यहाँ एक उदाहरण कार्यक्रम प्रदर्शित करने के लिए है
-1
4294967295
18446744073709551104
-512
1536
2047
1536 नंबर मैं उम्मीद कर रहा था है, लेकिन (uint32_t) (- 512) है जिस नंबर को मैं प्राप्त कर रहा था, जिसे आप कल्पना कर सकते हैं, चीजों को थोड़ा सा फेंक दिया।
तो, मुझे लगता है कि मेरा प्रश्न यह है: इस मामले में दो हस्ताक्षरित संख्याओं के बीच एक मॉड्यूलस ऑपरेशन, एक संख्या का उत्पादन करता है जो विभाजक (यानी ऋणात्मक संख्या) से अधिक है? क्या इस व्यवहार को प्राथमिकता दी गई है?
2600000000 एक int (या शायद 64-बिट int-long या long long) है, जो गुणा के परिणाम को (हस्ताक्षरित) लंबा होने का परिणाम हो सकता है। आप किस मंच पर हैं? – Random832