编写一个程序来交换整数中的奇偶位,最少需要多少步?

3

我正在尝试解决这个问题,我的代码如下:

#include<stdio.h>
int main() {
    int a, b = 0xaaaaaaaa, c = 0x55555555;
    printf("\n enter the number: \n");
    scanf("%d", & a);
    a = ((a & b) >> 1) | ((a & c) << 1);
    printf("\n %d", a);
}

但我得到了一些奇怪的输出..有人能告诉我我犯了什么错误吗?


无论我输入什么数字,都只会得到一个。 - learning_bee
@learning_bee:当我运行你的代码时,我得到的结果不是这样的。 (例如,请参见http://ideone.com/BbJRh)。 - Oliver Charlesworth
1
@learning_bee:如果你要改变 +,把它改成 | 而不是 ||。但是在这种特殊情况下,+ 是有效的,因为数据模式的原因。 - grok12
@grok12:你能详细解释一下为什么这样可以运行,以及有哪些“特殊情况”吗? - Ian Dallas
@grok12-我改了一下,发现输出还是1。 - learning_bee
显示剩余2条评论
6个回答

11

你的想法是好的。 也许你得到了奇怪的输出,因为位移操作并不像你期望的那样工作。

你的变量类型是int。这意味着它们是有符号的。当对有符号整数进行位移操作时,还有一些关于最高位比特如何传播的额外规则。简单地说,当有符号整数向右移位时,最高比特不一定为零,它会从旧的最高位值中复制。

尝试用unsigned int替换int


#include<stdio.h> int main() { unsigned int a; int b=0xaaaaaaaa,c=0x55555555; printf("\n 输入数字: \n"); scanf("%d",&a); a=((a&b)>>1)||((a&c)<<1); printf("\n %d",a);} - learning_bee
<< 和 >> 是标准的算术移位吗?我认为逻辑移位更有用。 - ShinTakezou
4
对于有符号整数,<< 在负值或正值溢出时具有未定义的行为,而>> 对负值具有实现定义的行为。不要在有符号类型中使用位移运算。按照valdo的建议,将您的类型更改为unsigned,您的代码将正常工作。 - R.. GitHub STOP HELPING ICE

1
在我的电脑上,这段代码完美地运行了,只是把加号改为了竖杠。
#include <stdio.h>

int main() {
    int a, b = 0xaaaaaaaa, c = 0x55555555;
    printf("\n enter the number: \n");
    scanf("%d", & a);
    a = ((a & b) >> 1) | ((a & c) << 1);
    printf("\n %d\n", a);
}

输出:

 enter the number: 
2
 1    
 enter the number: 
1
 2

0

虽然这个解决方案需要更多的迭代,但为了易于理解,请尝试这个。

void swapEvenOddBits()    //function to swap the even and odd bits
{       
    unsigned int num=0,even=0,odd=0;
    scanf("%u",&num);  //enter the number

    for(int i=1; i<32; i=i+2){
        even=num&(1<<(i-1));   
        odd=num&(1<<i);     
        num=num-even-odd;   

        even=even<<1;       
        odd=odd>>1;         
        num=num+even+odd;   
        //printf("%u  %d:%d  %d:%d  \n",num,i-1,even,i,odd); //track iterations with this
    }
    printf("%u",num);  //end result
}

0
unsigned char
swapOddEvenBits(unsigned char num)
{
    unsigned char odd_bits = num & 0xAA;
    unsigned char even_bits = num & 0x55;

    odd_bits >>= 1;
    even_bits <<= 1;

    return (odd_bits | even_bits);
}

0
你遇到的问题是有符号整数向右移位,导致末尾两位数字为11,因为你将最后四位二进制数与1010进行了按位或操作。在按位或操作之后,最后四位二进制数看起来像是1101。

-4
import java.io.*;
public class EvenOdd {

    public static void main(String[] args) 
    {
        int b = 0xaaaaaaaa, c = 0x55555555;
        System.out.println("enter number:");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String n="";
        try {
            n = br.readLine();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        int num = Integer.parseInt(n);
        num = ((num&b)>>1)|((num&c)<<1);
        System.out.println(num);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接