1.先贴我的代码,VC6.0开发环境下去掉第5行。
1 #include<stdio.h>
2 #include<stdlib.h>
3
4 int main(){ 5 setvbuf(stdout,NULL,_IONBF,0); 6 int value; 7 int getodds(int value); 8
9 printf("Input the value:"); 10 scanf("%o",&value); 11
12 printf("The result is %o.",getodds(value)); 13
14 return EXIT_SUCCESS; 15 } 16
17 int getodds(int value){ 18 int result=0; 19 int i; 20 int t; 21 for(i=0;i<8;i++) 22 { 23 t=1<<(2*i+1); 24 result=result+((value&t)>>(i+1)); 25 } 26 return result; 27 }
我的思路是这样的:
把二进制数的奇数位,共8位,依次存放到另一个二进制数的后8位中。解释如下:
从后往前,每次取二进制数奇数位中的1位,将得到的数分别右移若干位,循环8次,将每次右移后的数相加即可。
1). xxxx xxxx xxxx xxxx
& 0000 0000 0000 0010 1<<1
0000 0000 0000 00x0
0000 0000 0000 000x 右移1位
2). xxxx xxxx xxxx xxxx
& 0000 0000 0000 1000 1<<3
0000 0000 0000 x000
0000 0000 0000 00x0 右移2位
3). xxxx xxxx xxxx xxxx
& 0000 0000 0010 0000 1<<5
0000 0000 00x0 0000
0000 0000 0000 0x00 右移3位
……循环8次,将每次的和相加,即为最后的值。
循环变量i 0 1 2 3 4……
1左移的次数 1 3 5 7 9…… 2*i+1
相与后的数右移的次数 1 2 3 4 5…… i+1
2.再贴上谭浩强的思路:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<math.h>
4
5 int main(){ 6 setvbuf(stdout,NULL,_IONBF,0); 7 unsigned short value; 8 unsigned short getodds(unsigned short); 9
10 printf("Input the value:"); 11 scanf("%o",&value); 12
13 printf("The result is %o.",getodds(value)); 14
15 return EXIT_SUCCESS; 16 } 17
18 unsigned short getodds(unsigned short value){ 19 unsigned short result=0; 20 int i; 21 unsigned short a,b,c,power; 22 for(i=0;i<8;i++) 23 { 24
25 power=pow(2,7-i); 26 a=value>>(15-2*i); 27 b=a<<15; 28 c=b>>15; 29 result=result+c*power; 30 } 31 return result; 32 }
这个解法的思路是这样的,依次取出奇数位的值,再乘以相应的权重,然后将每次的值相加。
比如,
取第1位的值是这样的,将二进制数右移15位,第1位的值就到了最后1位,然后将二进制数左移15位,再右移15位,所得的数就是第1位的值了,1或者0,再乘以权重2**7;
第3位,将二进制数右移13位,第3位的值就到了最后1位,然后将二进制数左移15位,再右移15位,所得的数就是第3位的值了,1或者0,再乘以权重2**6;
依次类推。先左移15位,再右移15位的目的是将除要取出的位之外的其它位变为0。
这个算法必须用短整型,刚开始我在我的代码上按照谭浩强的算法进行修改之后,一直出不来正确结果,调试半天,发现必须用短整型。我的算法不存在这个问题。