पर 2^31 असाइन करने के बाद अजीब परिणाम प्रश्न शीर्षक के रूप में, हस्ताक्षर किए गए और हस्ताक्षरित 32-बिट पूर्णांक चर के लिए 2^31 असाइन करने से एक अप्रत्याशित परिणाम मिलता है।एक हस्ताक्षरित और हस्ताक्षरित 32-बिट पूर्णांक चर
MyPC/# c++ test.cpp -o test
MyPC/# ./test
18446744071562067968 <- Should be 2^31 right?
-2147483648 <- This is correct (-2^31 because of the sign bit)
size of ULL: 8, size of LL: 8
मैं फिर एक और समारोह p()
कहा, यह करने के लिए:
#include <cstdio>
using namespace std;
int main()
{
unsigned long long n = 1<<31;
long long n2 = 1<<31; // this works as expected
printf("%llu\n",n);
printf("%lld\n",n2);
printf("size of ULL: %d, size of LL: %d\n", sizeof(unsigned long long), sizeof(long long));
return 0;
}
यहाँ उत्पादन है:
यहाँ लघु कार्यक्रम (C++
में) है, जो मैं क्या हो रहा है यह देखने के लिए किया जाता है :
void p()
{
unsigned long long n = 1<<32; // since n is 8 bytes, this should be legal for any integer from 32 to 63
printf("%llu\n",n);
}
संकलन और चलने पर, यह भ्रमित है डी मुझे और भी अधिक:
MyPC/# c++ test.cpp -o test
test.cpp: In function ‘void p()’:
test.cpp:6:28: warning: left shift count >= width of type [enabled by default]
MyPC/# ./test
0
MyPC/
संकलक बाएं शिफ्ट गणना के बारे में शिकायत क्यों करनी चाहिए? sizeof(unsigned long long
) 8 लौटाता है, तो इसका मतलब यह नहीं है कि 2^63-1 उस डेटा प्रकार के लिए अधिकतम मान है?
मुझे लगा कि शायद n * 2 और एन < < 1, हमेशा एक ही तरीके से व्यवहार नहीं है, इसलिए मैं इस कोशिश की:
void s()
{
unsigned long long n = 1;
for(int a=0;a<63;a++) n = n*2;
printf("%llu\n",n);
}
इस रूप में 2^63 का सही मूल्य देता है आउटपुट जो 9223372036854775808
है (मैंने इसे पायथन का उपयोग करके सत्यापित किया है)। लेकिन बाएं बकवास करने में क्या गलत है? विकिपीडिया
मूल्य बह निकला नहीं है -
n द्वारा एक बाएं अंकगणित पारी 2 n से गुणा करने के बराबर है
(मूल्य अतिप्रवाह नहीं करता है प्रदान की) , केवल एक ऋण चिह्न दिखाई देगा क्योंकि मान 2^63 है (सभी बिट सेट हैं)।
मैं अभी भी यह पता लगाने में असमर्थ हूं कि बाएं शिफ्ट के साथ क्या चल रहा है, क्या कोई इसे समझा सकता है?
पुनश्च: इस कार्यक्रम के एक 32-बिट सिस्टम चल रहा है लिनक्स टकसाल पर चलाया गया था (है कि अगर मदद करता है)
यह 'होना चाहिए अहस्ताक्षरित लंबे एन = 1ULL << 31;' – kirilloid
भगवान! क्या यह आसान था ?! मैंने इसके बारे में क्यों नहीं सोचा। वैसे भी, हाँ 1ULL << 31 काम करता है। तो धन्यवाद! – Rushil