在上篇文章《C语言小程序:打印整数的二进制》中,大笨兔给出了一个打印二进制整数的程序。程序的算法很简单,从整数的最高位开始访问,然后逐一打印出来。但是在那个程序中有一点小问题,如果你只打印一个8位的整数,前面会同时打印几十个0,有点影响阅读。
后来Like likes like同学评论说可以让用户自己控制打印多少位:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void print_int_bit(int num, unsigned int size) { unsigned int length = 4 * sizeof(num); unsigned int index = (1 << (length - 1)); if ((length > size) && (size > 0)) { index = (1 << (size - 1)); } while (index > 0) { putchar((num & index) ? '1' : '0'); index >>= 1; } } /* length 为应对32位与64位机的差异 */ |
虽然可以通过设置第二个参数的方式来改变这一点,但是我还是感觉这有点麻烦了。有没有让程序自己判断那些事要打多少位的呢?
对于无符号数来说,8位二进制数最大能表示255,16则是65535,32位这是0xffffffff (是多少??)。那么能不能通过判断这个数的在那个区间来决定打印它多少位呢?
比如127,在0-255这个区间内,只要打印8位就好了:
01111111
好吧,编写代码
1 2 3 4 5 6 7 8 9 10 |
if (value <= (unsigned char)0xff) index = 0x80; else if (value <= (unsigned short)0xffff) { index = 0x8000; } else if (value <= (unsigned int)0xffffffff) { index = 0x80000000; } |
编译,运行,right!
但是对于负数呢?我想过将其强制转换为无符号数(这样不为改变其二进制形式),然后按照上面的代码算出index,再打印。但是发现不行。
比如-12的二进制是:
11110100
在32位下(print_int_bit函数是用int作为参数的,-12传入会被强制转换成32位整数),-12的二进制就成了下面的形式:
11111111111111111111111111110100
将其转换成unsigned类型后,它的值就变成了
4294967284
用海盗船长的话说就是“河老子一跳”!!!
怎么办呢?最后找到一个解决办法,将负数转正,判断属于哪个区间。在C语言学习数据类型的时候,书上说(哈哈),8位有符号数的表示范围是 -128 – 127,16位则是…
那么我可以通过对负数的绝对值进行判断,从而决定它要打印多少位。最后的代码是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
void print_int_bit03(int value) { unsigned int index = 0x80000000; if (value >= 0) { /* ** 处理非负数的情况 */ if (value <= (unsigned char)0xff) index = 0x80; else if (value <= (unsigned short)0xffff) { index = 0x8000; } else if (value <= (unsigned int)0xffffffff) { index = 0x80000000; } } else { /* ** 处理负数的情况 */ if ( (-value) <= (unsigned char)0x80) index = 0x80; else if ( (-value) <= (unsigned short)0x8000) { index = 0x8000; } else if ( (-value) <= (unsigned int)0x80000000) { index = 0x80000000; } } /* 打印 */ while (index > 0) { putchar(value & index ? '1' : '0'); index >>= 1; } putchar('\n'); /* 方便测试 :) */ } |
代码还有不完善的地方,比如对于64位机的处理。如果你有更好的方法,欢迎指教!
发表评论
要发表评论,您必须先登录。