2012-03-14 6 views
11

मुझे int64_t को char array और back में कनवर्ट करने में समस्या हो रही है। मुझे नहीं पता कि नीचे दिए गए कोड में क्या गलत है, यह मेरे लिए पूर्ण तार्किक अर्थ बनाता है। कोड दिखाए गए अनुसार a के लिए काम करता है, लेकिन दूसरा नंबर b नहीं है जो स्पष्ट रूप से int64_t की सीमा में आता है।मैं 64 बिट पूर्णांक को चार सरणी में वापस कैसे बदलूं?

#include <stdio.h> 
#include <stdint.h> 

void int64ToChar(char mesg[], int64_t num) { 
    for(int i = 0; i < 8; i++) mesg[i] = num >> (8-1-i)*8; 
} 

int64_t charTo64bitNum(char a[]) { 
    int64_t n = 0; 
    n = ((a[0] << 56) & 0xFF00000000000000U) 
    | ((a[1] << 48) & 0x00FF000000000000U) 
    | ((a[2] << 40) & 0x0000FF0000000000U) 
    | ((a[3] << 32) & 0x000000FF00000000U) 
    | ((a[4] << 24) & 0x00000000FF000000U) 
    | ((a[5] << 16) & 0x0000000000FF0000U) 
    | ((a[6] << 8) & 0x000000000000FF00U) 
    | (a[7]  & 0x00000000000000FFU); 
    return n; 
} 

int main(int argc, char *argv[]) { 
    int64_t a = 123456789; 
    char *aStr = new char[8]; 
    int64ToChar(aStr, a); 
    int64_t aNum = charTo64bitNum(aStr); 
    printf("aNum = %lld\n",aNum); 

    int64_t b = 51544720029426255; 
    char *bStr = new char[8]; 
    int64ToChar(bStr, b); 
    int64_t bNum = charTo64bitNum(bStr); 
    printf("bNum = %lld\n",bNum); 
    return 0; 
} 

उत्पादन

aNum = 123456789 
bNum = 71777215744221775 

कोड भी दो चेतावनी है कि मैं नहीं जानता कि से छुटकारा पाने के लिए कैसे देता है।

warning: integer constant is too large for ‘unsigned long’ type 
warning: left shift count >= width of type 
+3

दूसरी चेतावनी कुंजी है। '<<' के संचालन को 'int' में पदोन्नत किया जाता है, इसलिए 'एक [0] << 56' हमेशा 0 होगा।' ((Int64_t) एक [0]) 'आदि पहली चेतावनी लगभग 51544720029426255 है , आपको 51544720029426255LL कहना होगा। –

+0

http://ideone.com/dKIWT – aroth

उत्तर

7

यह बल्कि सरल है, समस्या यह है कि आप चार सरणी लेकिन के आकार में बिट्स जा रहे है a[i] 4 बाईस (int तक अपस्टास्ट) है, इसलिए आपकी शिफ्ट बस सीमा से अधिक हो जाती है। अपने कोड में इस जगह का प्रयास करें:

int64_t charTo64bitNum(char a[]) { 
    int64_t n = 0; 
    n = (((int64_t)a[0] << 56) & 0xFF00000000000000U) 
    | (((int64_t)a[1] << 48) & 0x00FF000000000000U) 
    | (((int64_t)a[2] << 40) & 0x0000FF0000000000U) 
    | (((int64_t)a[3] << 32) & 0x000000FF00000000U) 
    | ((a[4] << 24) & 0x00000000FF000000U) 
    | ((a[5] << 16) & 0x0000000000FF0000U) 
    | ((a[6] << 8) & 0x000000000000FF00U) 
    | (a[7]  & 0x00000000000000FFU); 
    return n; 
} 

इस तरह आप बदलाव करने से पहले एक 64 बिट संख्या के लिए char डाली होगा और आपके पास सीमा पर नहीं जाना होगा। आप सही परिणाम प्राप्त करेंगे:

entity:Dev jack$ ./a.out 
aNum = 123456789 
bNum = 51544720029426255 

बस एक ओर ध्यान दें, मुझे लगता है कि यह भी ठीक काम करेगा, यह मानते हुए आप चार सरणी के अंदर झांक सकते की जरूरत नहीं है:

#include <string.h> 

void int64ToChar(char a[], int64_t n) { 
    memcpy(a, &n, 8); 
} 

int64_t charTo64bitNum(char a[]) { 
    int64_t n = 0; 
    memcpy(&n, a, 8); 
    return n; 
} 
+0

मैं int64_t वैरिएबल पर आपके वैकल्पिक, memcpy को सीधे पसंद करूंगा, लेकिन मुझे नहीं लगता कि यह काम करेगा, उदाहरण के लिए: char * szInput = "51544720029426255";/* 17 बाइट्स, 8 बाइट्स से अधिक */ memcpy (& n, szInput, 8); परिणामस्वरूप अतिप्रवाह होगा, आपको नहीं लगता? धन्यवाद – Zennichimaro

+0

नहीं, क्योंकि आप यह निर्दिष्ट कर रहे हैं कि आप तीसरे पैरामीटर के माध्यम से किसी भी मामले में केवल 8 बाइट कॉपी करेंगे। – Jack

+1

ओह या .. लेकिन फिर यह केवल पहले 8 बाइट्स कॉपी करेगा, cout << n; प्रिंट करेगा: 51544720, है ना? 51544720029426255 int64_t में होना चाहिए क्योंकि अधिकतम मूल्य 9223372036854775807 है। – Zennichimaro

0

क्या आप 32 बिट मशीन पर हैं? आईआईआरसी मुझे लगता है कि यू प्रत्यय का मतलब केवल 'हस्ताक्षरित int' या 'unsigned long' है, दोनों 32 बिट मशीन पर 32 बिट हैं। मुझे लगता है कि आप अपने बिट पाली में एक 'अहस्ताक्षरित लंबे' (64 बिट) शाब्दिक चाहते हैं, या 0xFF00000000000000ULL

http://en.kioskea.net/faq/978-c-language-handling-64-bit-integers#unsigned-64-bit-integer

0

charTo64bitNum में आप इससे पहले कि आप बदलाव 64-बिट के लिए चार कास्ट करने के लिए की जरूरत है:

(((int64_t)a[0] << 56) & 0xFF00000000000000U) 
1
void int64ToChar(char mesg[], int64_t num) { 
    *(int64_t *)mesg = num; //or *(int64_t *)mesg = htonl(num); 

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