2012-02-04 24 views
9

में सी रिवर्स बिट्स मैं बिटवाई ऑपरेटरों का उपयोग करके बाइनरी में एक हस्ताक्षरित पूर्णांक को परिवर्तित कर रहा हूं, और वर्तमान में बिट 0 या 0 और आउटपुट की जांच करने के लिए पूर्णांक & 1 पूर्ण करता है, फिर 2 से विभाजित करने के लिए दाएं स्थानांतरित करें। हालांकि बिट्स को गलत क्रम (रिवर्स) में वापस कर दिया जाता है, इसलिए मैंने शुरुआत से पहले पूर्णांक में बिट्स ऑर्डर को उलट दिया।सी अप्रतिबंधित पूर्णांक

क्या ऐसा करने का कोई आसान तरीका है?

उदाहरण: तो अगर मैं दिया हूँ अहस्ताक्षरित पूर्णांक 10 = 1010

while (x not eq 0) 
    if (x & 1) 
    output a '1' 
    else 
    output a '0' 
    right shift x by 1 

इस रिटर्न 0101 जो सही नहीं है ... इसलिए मैं बिट्स के क्रम को उल्टा करने के लिए सोच रहा था मूल रूप से पहले से चल रहा है लूप, लेकिन मुझे यकीन नहीं है कि यह कैसे करें?

+7

आप कुछ कोड पोस्ट करना चाहिए इसे थोड़ा और स्पष्ट करने के लिए (कोई इरादा नहीं है)। – user973572

+0

उदाहरण ओपी –

+0

में संभावित डुप्लिकेट [बिट रिवर्सल के लिए सर्वश्रेष्ठ एल्गोरिदम (एमएसबी-> एलएसबी से एलएसबी-> एमएसबी) सी में] (http://stackoverflow.com/questions/746171/best-algorithm-for-bit -reversal-from-msb-lsb-to-lsb-msb-in-c) –

उत्तर

18

किसी शब्द में बिट्स को उलटना परेशान है और इसे रिवर्स ऑर्डर में आउटपुट करना आसान है। उदाहरण के लिए,

void write_u32(uint32_t x) 
{ 
    int i; 
    for (i = 0; i < 32; ++i) 
     putchar((x & ((uint32_t) 1 << (31 - i)) ? '1' : '0'); 
} 

यहाँ सा आदेश को पलटने के लिए ठेठ समाधान है:

uint32_t reverse(uint32_t x) 
{ 
    x = ((x >> 1) & 0x55555555u) | ((x & 0x55555555u) << 1); 
    x = ((x >> 2) & 0x33333333u) | ((x & 0x33333333u) << 2); 
    x = ((x >> 4) & 0x0f0f0f0fu) | ((x & 0x0f0f0f0fu) << 4); 
    x = ((x >> 8) & 0x00ff00ffu) | ((x & 0x00ff00ffu) << 8); 
    x = ((x >> 16) & 0xffffu) | ((x & 0xffffu) << 16); 
    return x; 
} 
+0

क्या आप मुझे दूसरे भाग के आगे स्पष्टीकरण दे सकते हैं (या मुझे Google में डालने के लिए एक वाक्यांश दें)। यह मुझे समझ में नहीं आता है और थोड़ा सा प्रतिनिधित्व के बारे में मेरा ज्ञान मेरे विचार से भी बदतर है। पहले ही, आपका बहुत धन्यवाद। – AoeAoe

+1

@AoeAoe: यह थोड़ा सा हैकिंग हैक। मैं बाइनरी में संख्याओं को लिखने का सुझाव देता हूं यदि आप यह समझना चाहते हैं कि यह कैसे काम करता है। प्रत्येक पंक्ति बिट्स के आधे हिस्से के आधे हिस्से के साथ आदान-प्रदान करती है, और कोर में पांच पंक्तियां किसी भी क्रम में लिखी जा सकती हैं। –

+2

यहां स्पष्टीकरण है: हमें बी = 1 से शुरू होने वाले ब्लॉक आकार बी में सभी बिट्स को विभाजित करने दें। अब हम प्रत्येक आसन्न ब्लॉक को स्वैप करते हैं। डबल ब्लॉक आकार और दोहराना। तब तक जारी रखें जब तक कि ब्लॉक आकार शब्द का आधा आकार न हो। 32 बिट्स के लिए, यह 5 कदम होगा। प्रत्येक चरण को लिखा जा सकता है ((एक्स और मास्क) << बी) | ((एक्स और मास्क ') << बी)। इस प्रकार 5 बयान में, हम 32 बिट int को उलट सकते हैं। – ShitalShah

2

आप सही बजाय बाईं से चला जाता, कि करने के लिए MSB से एक एक बदलाव है LSB, उदाहरण के लिए:

unsigned n = 20543; 
unsigned x = 1<<31; 
while (x) { 
    printf("%u ", (x&n)!=0); 
    x = x>>1; 
} 
+0

@ सेठ कार्नेगी नहीं, यह एक्स >> 1 है क्योंकि x = 1 << 31 इसलिए हम एमएसबी से एलएसबी तक जा रहे हैं या बिट्स के क्रम को उलट करने के लिए बाएं से दाएं हैं। – iabdalkader

+0

आह मैंने 'x' को' n' से भ्रमित कर दिया था। –

1

आप की तरह आप उन्हें उत्पादन बिट्स रिवर्स सकता है, और इसके बजाय उन्हें एक अन्य पूर्णांक में स्टोर, और इसे फिर से कार्य करें:

आप प्रमुख निकालना चाहते हैं

unsigned int mask = 1 << ((sizeof(unsigned int) * CHAR_BIT) - 1); 
while (mask > 0) 
{ 
    bit = original_int & mask; 
    mask = mask >> 1; 
    printf("%d", (bit > 0)); 
} 

0 के आप या तो इंतजार एक 1 मुद्रित करने के लिए के लिए, या एक प्रारंभिक जाने के माध्यम से कर सकते हैं:

for (i = 0; i < (sizeof(unsigned int) * CHAR_BIT); i++) 
{ 
    new_int |= (original_int & 1); 
    original_int = original_int >> 1; 
    new_int = new_int << 1; 
} 

या आप बस विपरीत कर सकता है, अपने मुखौटे बदलाव:

unsigned int mask = 1 << ((sizeof(unsigned int) * CHAR_BIT) - 1); 
while ((mask > 0) && ((original_int & mask) == 0)) 
    mask = mask >> 1; 
do 
{ 
    bit = original_int & mask; 
    mask = mask >> 1; 
    printf("%d", (bit > 0)); 
} while (mask > 0); 

इस तरह से आप पहली बार 1 पर मुखौटा स्थापित करेंगे मुद्रित करने के लिए जा और अग्रणी 0 के

के बारे में भूल लेकिन याद रखें: एक पूर्णांक के बाइनरी मान मुद्रण बस किया जा सकता है printf

+0

बस 8 से आकार को गुणा करना याद रखें, और आपका पहला समाधान ठीक होगा। (दूसरा ओवरफ्लो होगा, लेकिन कुछ सुधारों के साथ, यह काम कर सकता है) – asaelr

+2

अभी भी बेहतर है, 'CHAR_BIT' से गुणा करें। –

+0

इस मामले में आउटपुट से अग्रणी 0s को कैसे हटाया जाए? जब तक यह एक वास्तविक बिट नहीं मिला है तब तक मैं आउटपुट की जांच कर सकता हूं और नहीं, लेकिन यह बहुत ही सुरुचिपूर्ण प्रतीत नहीं होता है और यदि प्रोग्राम में इनपुट 0 है। –

2

आप बिट्स के माध्यम से बड़े अंत से थोड़ा अंत तक लूप कर सकते हैं।

#define N_BITS (sizeof(unsigned) * CHAR_BIT) 
#define HI_BIT (1 << (N_BITS - 1)) 

for (int i = 0; i < N_BITS; i++) { 
    printf("%d", !!(x & HI_BIT)); 
    x <<= 1; 
} 

कहाँ !! भी !=0 या >> (N_BITS - 1) लिखा जा सकता है।

+0

!! (x) == x नहीं है? डबल अस्वीकरण रद्द हो जाता है, और == 0 सत्य होगा, यानी 1 अगर यह 0 है तो यह बिट्स को फ़्लिप करता है। – iabdalkader

+0

@mux: नहीं, डबल अस्वीकृति केवल 0 और 1 के लिए रद्द हो जाती है। आप '== 0' के बारे में सही हैं, जो कि '! = 0' होना चाहिए था, क्षमा करें। –

+0

ओह, अब मैं इसे देखता हूं, कुछ! (! (512)) =! (0) = 1 धन्यवाद, मैं इसे बहुत अधिक असतत पर दोष देता हूं :) ... – iabdalkader

1
unsigned int rev_bits(unsigned int input) 
{ 
    unsigned int output = 0; 
    unsigned int n = sizeof(input) << 3; 
    unsigned int i = 0; 

    for (i = 0; i < n; i++) 
     if ((input >> i) & 0x1) 
      output |= (0x1 << (n - 1 - i)); 

    return output; 
} 
0

मैं ऐसे समाधान के साथ आया जिसने बिटवाई ऑपरेटरों के किसी भी एप्लिकेशन को शामिल नहीं किया है। यह अंतरिक्ष और समय दोनों के मामले में अक्षम है।

int arr[32]; 
for(int i=0;i<32;i++) 
{ 
    arr[i]=A%2; 
    A=A/2; 
} 
double res=1; 
double re=0; 
for(int i=0;i<32;i++) 
{ 
    int j=31-i; 
    res=arr[i]; 
    while(j>0) 
    { 
     res=res*2; 
     j--; 
    } 
    re=re+res; 
} 
cout<<(unsigned int)re; 
0

कोई भी पूर्णांक में रिवर्स बिट्स का गोलांग संस्करण है, अगर कोई एक की तलाश में है। मैंने इसे सी में स्ट्रिंग रिवर्स के समान दृष्टिकोण के साथ लिखा था। 0 से 15 (31/2) बिट्स पर जाकर, थोड़ा सा (31-i) के साथ थोड़ा सा स्वैप करें। कृपया निम्नलिखित कोड जांचें।

package main 
import "fmt" 

func main() { 
    var num = 2 
    //swap bits at index i and 31-i for i between 0-15 
    for i := 0; i < 31/2; i++ { 
     swap(&num, uint(i)) 
    } 
    fmt.Printf("num is %d", num) 
} 

//check if bit at index is set 
func isSet(num *int, index uint) int { 
    return *num & (1 << index) 
} 

//set bit at index 
func set(num *int, index uint) { 
    *num = *num | (1 << index) 
} 

//reset bit at index 
func reSet(num *int, index uint) { 
    *num = *num & ^(1 << index) 
} 

//swap bits on index and 31-index 
func swap(num *int, index uint) { 
    //check index and 31-index bits 
    a := isSet(num, index) 
    b := isSet(num, uint(31)-index) 
    if a != 0 { 
     //bit at index is 1, set 31-index 
     set(num, uint(31)-index) 
    } else { 
     //bit at index is 0, reset 31-index 
     reSet(num, uint(31)-index) 
    } 
    if b != 0 { 
     set(num, index) 
    } else { 
     reSet(num, index) 
    } 
}` 
0

आप एक unsigned 32-bit integer रिवर्स और निम्नलिखित reverse फंक्शन का उपयोग करके लौट सकते हैं:

unsigned int reverse(unsigned int A) { 
    unsigned int B = 0; 
    for(int i=0;i<32;i++){ 
     unsigned int j = pow(2,31-i); 
     if((A & (1<<i)) == (1<<i)) B += j; 
    } 
return B; 
} 

गणित पुस्तकालय शामिल करना न भूलें। हैप्पी कोडिंग :)

0

मेरा मानना ​​है कि सवाल यह पूछ रहा है कि रिवर्स ऑर्डर में आउटपुट कैसे करें।

मज़ा जवाब (प्रत्यावर्तन):

#include <stdio.h> 

void print_bits_r(unsigned int x){ 
    if(x==0){ 
     printf("0"); 
     return; 
    } 
    unsigned int n=x>>1; 
    if(n!=0){ 
     print_bits_r(n); 
    } 
    if(x&1){ 
     printf("1"); 
    }else{ 
     printf("0"); 
    } 
} 


void print_bits(unsigned int x){ 
    printf("%u=",x); 
    print_bits_r(x); 
    printf("\n"); 
} 

int main(void) { 
    print_bits(10u);//1010 
    print_bits((1<<5)+(1<<4)+1);//110001 
    print_bits(498598u);//1111001101110100110 
    return 0; 
} 

अपेक्षित उत्पादन:

10=1010 
49=110001 
498598=1111001101110100110 

अनुक्रमिक संस्करण (बंद उठाता पहली उच्च बिट):

#include <limits.h>//Defines CHAR_BIT 
//.... 
void print_bits_r(unsigned int x){ 
    //unsigned int mask=(UINT_MAX>>1)+1u;//Also works... 
    unsigned int mask=1u<<(CHAR_BIT*sizeof(unsigned int)-1u); 
    int start=0; 
    while(mask!=0){ 
     if((x&mask)!=0){ 
      printf("1"); 
      start=1; 
     }else{ 
      if(start){ 
       printf("0"); 
      } 
     } 
     mask>>=1; 
    } 
    if(!start){ 
     printf("0"); 
    }  
}