12.5 设计一个函数, 使给出一个数的原码, 能得到该数的补码.
这道题的表述又有些诡异了, 不知道大家是如何理解题意的.
很多同学写了这样的函数:
拿来一个数, 判断其正负.
如果为正则返回原数;
如果为负, 则按求补码的那套方法一通运算再返回结果. 当然, 最终的结果依然是返回原数, 因为本来负数就是用补码的形式存储的.
于是这个程序看起来就像什么也没做一样... 无论如何用printf( )来打印结果也看不出什么.
下面是我给出的一个解决方案, 好歹能让这道题目更直观一些.
这道题的表述又有些诡异了, 不知道大家是如何理解题意的.
很多同学写了这样的函数:
拿来一个数, 判断其正负.
如果为正则返回原数;
如果为负, 则按求补码的那套方法一通运算再返回结果. 当然, 最终的结果依然是返回原数, 因为本来负数就是用补码的形式存储的.
于是这个程序看起来就像什么也没做一样... 无论如何用printf( )来打印结果也看不出什么.
下面是我给出的一个解决方案, 好歹能让这道题目更直观一些.
- #include <stdio.h>
- #include <stdlib.h>
- //首先写了一个打印二进制形式数的函数. 以便能看清按位操作的过程
- void PrintIntBin (int num)
- {
- int i;
- int IOOO = 1 << sizeof (int) * 8 - 1; //IOOO就是那个最高位为1其余为全是0的int型的数, 目的见下面. 注意<<优先级低于加减号.
- printf ("%10d : ", num);
- for (i = 0; i < sizeof (int) * 8 ; i++ )
- {
- //这段其实就是拿num的每一位去和IOOO里那个仅有的1做比较, 以确定各位是0还是1. 从num的左端开始, 之后每次都会把num左移一位.
- //似乎改为每次将IOOO右移一位更容易理解一点. 但那样做的话IOOO必须声明为unsigned int型.
- //原因是有符号数如果最高位为1的话, 右移时左端的空缺会补入1而非0.
- if ( num & IOOO ) //如果num当前位为1的话, 写成if ( (num & IOOO) != 0 )也许更好懂些.
- printf ("%d", 1); //就打印1
- else //否则
- printf ("%d", 0); //就打印0
- num <<= 1; //即 num = num << 1;
- }
- printf ("/n");
- }
- //反正负数求补码求完了也还是自己,
- //这里我写的这个函数是将一个正数用求补码的方式来转换成对应的负数,
- //也就是将5转成-5.
- //同时利用上面那个函数来展现操作过程.
- int GetComp (int somePositiveNum)
- {
- if ( somePositiveNum < 0 ) //如果输入的本来就是负数姑且什么也不做
- {
- printf ("It's a negative number!/n");
- PrintIntBin ( somePositiveNum );
- return somePositiveNum;
- }
- else //这一段才是关键
- {
- //原正数
- int ret = somePositiveNum;
- printf ("Original positive number :/n");
- PrintIntBin (ret);
- //按位取反之后
- ret = ~ret;
- printf ("After ~ :/n");
- PrintIntBin (ret);
- //再加个1
- ret = ret + 1;
- printf ("After +1 :/n");
- PrintIntBin (ret);
- return ret;
- }
- }
- int main (void)
- {
- //前三句是测试一下PrintIntBin( )是否工作正常..
- PrintIntBin (1);
- PrintIntBin (8);
- PrintIntBin (-1);
- //这一句才是主要的, 用5做试验, 看看能不能顺利地转成-5.
- GetComp (5) ;
- return 0;
- }