2010-03-16 10 views
5

कृपया नीचे सरल कोड देखें:नकारात्मक मूल्य के साथ अहस्ताक्षरित लंबे

#include <iostream> 
#include <stdlib.h> 

using namespace std; 


int main(void) 
{ 
    unsigned long currentTrafficTypeValueDec; 
    long input; 
    input=63; 
    currentTrafficTypeValueDec = (unsigned long) 1LL << input; 
    cout << currentTrafficTypeValueDec << endl; 
    printf("%u \n", currentTrafficTypeValueDec); 
    printf("%ld \n", currentTrafficTypeValueDec); 
    return 0; 
} 

क्यों printf() को प्रदर्शित करता है currentTrafficTypeValueDec (अहस्ताक्षरित लंबे) नकारात्मक मूल्य के साथ?

उत्पादन होता है:

9223372036854775808 
0 
-9223372036854775808 

उत्तर

3

बिट्स के साथ मज़ा ...

cout एक अहस्ताक्षरित लंबे समय के रूप में नंबर प्रिंट कर रहा है, सभी 64 बिट्स महत्वपूर्ण और अहस्ताक्षरित द्विआधारी पूर्णांक के रूप में प्रिंट कर रहे हैं (मुझे लगता है कि प्रारूप यहाँ %lu होगा)।

printf(%u ... इनपुट को सामान्य हस्ताक्षरित पूर्णांक (32 बिट्स) के रूप में मानता है। इससे 33 से 64 बिट्स बंद हो जाते हैं - शून्य छोड़कर।

printf(%ld ... इनपुट को 64 बिट हस्ताक्षरित नंबर के रूप में मानता है और इसे प्रिंट करता है।

जो चीज आपको पिछले printf के बारे में भ्रमित करने में मिल सकती है वह यह है कि यह cout के समान पूर्ण मूल्य देता है, लेकिन एक ऋण चिह्न के साथ। एक हस्ताक्षरित पूर्णांक के रूप में देखते समय सभी 64 बिट्स पूर्णांक मान के उत्पादन में महत्वपूर्ण होते हैं। हालांकि हस्ताक्षरित संख्याओं के लिए, बिट 64 साइन बिट है। जब साइन बिट सेट होता है (जैसा कि यह आपके उदाहरण में है) यह इंगित करता है कि शेष 63 बिट्स को 2's compliment में दर्शाए गए नकारात्मक संख्या के रूप में माना जाना चाहिए। सकारात्मक संख्या केवल उनके बाइनरी मान को दशमलव में परिवर्तित करके मुद्रित की जाती है। हालांकि ऋणात्मक संख्या के लिए निम्नलिखित होता है: नकारात्मक संकेत मुद्रित करें, XOR बिट्स 1 से 63 तक बाइनरी '1' बिट्स के साथ, परिणाम में 1 जोड़ें और हस्ताक्षरित मान मुद्रित करें। साइन बिट (बिट 64) को छोड़कर आप 63 '0' बिट्स के साथ समाप्त हो जाते हैं, '1' बिट्स के साथ एक्सओआरिंग आपको 63 '1' बिट्स देता है, +1 जोड़ता है और पूरी चीज आपको एक हस्ताक्षरित पूर्णांक देने के लिए रोल करती है 64 '1' पर सेट है और बाकी को '0' पर सेट किया गया है - जो आपको cout के साथ मिलती है, लेकिन ऋणात्मक संख्या के रूप में।

एक बार जब आप बाहर काम किया है क्यों ऊपर स्पष्टीकरण सही है आप भी डालने की this

13

आप इसे एक अहस्ताक्षरित मूल्य पारित करके printf जबकि प्रारूप कल्पना ने कहा कि यह एक हस्ताक्षरित एक होगा झूठ बोला।

+0

दिलचस्प तरीका :) – Tim

17

%d एक हस्ताक्षरित फॉर्मेटर है। के रूप में currentTrafficTypeValueDec (63 वें पावर से 2) के बिट्स को दोबारा परिभाषित करना नकारात्मक मान देता है। तो printf() एक नकारात्मक संख्या प्रिंट करता है।

शायद आप %lu का उपयोग करना चाहते हैं?

1

परिवर्तक अपने प्रकार को अपने आप में नहीं लेता है। आप इसके प्रकार printf करने के लिए निर्दिष्ट करते हैं। आज़माएं:

printf("%lu \n", currentTrafficTypeValueDec); 

क्योंकि ld मींड लंबे समय से हस्ताक्षर किए गए हैं कि यह सच नहीं है।

5

क्योंकि आप 1 को चर के हस्ताक्षर बिट में स्थानांतरित कर रहे हैं। जब आप इसे हस्ताक्षरित मान के रूप में प्रिंट करते हैं, तो यह नकारात्मक होता है।

+0

+1, सर्वश्रेष्ठ उत्तर से बाहर समझ बनाने के लिए सक्षम होना चाहिए। –

0

आप %ld, या एक लंबे हस्ताक्षर किए गए दशमलव को प्रिंट कर रहे हैं। यही कारण है कि यह एक नकारात्मक मूल्य लौट रहा है।

संबंधित मुद्दे