the beauty of C++
9月21日,对本文从格式到部分内容上都进行了修改另外,鉴于某些转载没有注明出处,考虑到版权问题,特声明如下:作者:翼帆@cppblog 原文地址:http://www.cppblog.com/xiaoyisnail/archive/2009/09/19/96707.html本文版权归作者和cppblog共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 今天看了一位师兄去年的笔经总结,其中有一题是“不许用%和/来实现求任意数除以3的余数”,我想考官的目的应该是想考察学生对位运算的熟悉程度吧,于是我把题目扩展成“只能用+,-和位运算实现正整数除法(/)和取模(%)”,注意:这里不能使用其它的库例程来辅助计算,如log,log10等。在思考这道题目的过程中,我又涉及到了许多二进制相关的题目,如: 判断给定的整数是不是2的整数次幂 判断给定的整数是不是4的整数次幂 求给定整数的二进制表示中1的个数 求给定整数的二进制表示中0的个数 求给定整数的二进制表示中最高位1的位置 求大于等于给定整数的最小的2的整数次幂 求给定整数的二进制表示的有效位数 ... 9月21日补充:这里只考虑值为正整数的情况。 这些题目都是经典老题,频繁出现于各类笔试面试题中,除了能考察位运算外,还能考察应聘者能否给出创新的算法来更好地解决问题。可以说这些题目都不难,如果使用32位的int来表示整数的话,蛮力法都可以比较好地完成任务,但是如果想尽可能地提高效率,那就需要动一番脑经了。下面给出我对这些问题的整理和C++实现,并在下次的文章中给出只用+,-和位运算实现的正整数除法和取模。 从某种意义上讲,特别是从充分利用底层硬件的计算能力(利用特殊的cpu指令)来看,这些解法肯定不是最优的,所以还希望大侠们多多指点。 判断给定的整数是不是2的整数次幂 这应该是最简单的,利用最高位是1,其后所有位为0的特性,常数时间解决问题:
posted on 2009-09-19 13:58 翼帆 阅读(8265) 评论(3) 编辑 收藏 引用 所属分类: 算法
那么n|=n-1就把n的二进制表示中最低位1后的所有0置1,再加上1,那么就把最低位1左移了一位。 假设n=0x1100,那么n-1 = 0x1011, n | (n - 1) = 0x1111.跟你上面描述不一致. 回复 更多评论
总结的不错 回复 更多评论
求给定整数的二进制表示的有效位数 可以binary search最高位置1的位置 int get_leftmost_set_bit(unsigned int n) { int l, u, m, t1, t2; l = 0; u = sizeof(int) * 8 - 1; while (l <= u) { m = l + (u - l)/2; t1 = n & (~((1 << m) - 1)); t2 = n & (~((1 << (m + 1)) - 1)); if (t1 && !t2) { return m; } else if (t1 && t2) { l = m + 1; } else { u = m - 1; } } return -1; } 回复 更多评论