使用PHP,给定一个数,判断这个数是不是二的N次方
这样看似简单的一个面试题, 实际牵出了不少基础知识,本章在为你们补习基础知识的状况下来解答这道题。先亮出答案php
function exponentiation($number) { if ($number < 0) { return false; } if (($number & ($number - 1)) == 0) { return true; } else { return false; } } exponentiation (2); exponentiation (8); exponentiation (16); exponentiation (32); exponentiation (128);
这是查阅后的最最标准的答案,其余相似经过循环等等答案就略过把。程序员
实际这道面试题考的并不是是算法,而是做为开发人员的你“底子”够不够。
运算符应该是每门语言hello world 后立马要学习的。运算符分不少种,赋值运算符,比较运算符等等。我想大多自学或者培训出道的没有通过系统化学习的童鞋的,对这块的知识应该很薄弱把。固然赋值、比较什么的很熟悉,因业务基本逃不过这些。但对位运算符,你真的吃透了吗?面试
这道题的考点一是位运算符的使用,上面说过了本题考察的并不是算法,而是你对二进制的了解,而在php中能操做二进制的运算符 貌似 (个人知识范围内) 只有位运算符
本道面试题用到了 & 因此不详解其余的运算符,须要更多了解请移步官方
http://php.net/manual/zh/lang...算法
运算符 | 附加信息 |
---|---|
& | 按位与运算符 |
^ | 按位异或运算符 |
按位与以简单易懂的方式来说就是二进制位不相同的抵消,相同的保留学习
举几个栗子spa
公式 -> 转为二进制后的公式 -> 二进制结果 -> 十进制结果
2 & 3 -> 0010 & 0011 -> 0010 = 2 10 & 7 -> 1010 & 0111 -> 0010 = 2 32 & 70 -> 0100000 & 1000110 -> 0000000 = 0
按位异或以简单易懂的方式来说就是二进制位相同的抵消,不相同的保留.net
举几个栗子3d
公式 -> 转为二进制后的公式 -> 二进制结果 -> 十进制结果
2 ^ 3 -> 0010 ^ 0011 -> 0001 = 1 10 ^ 7 -> 1010 ^ 0111 -> 1101 = 13 32 ^ 70 -> 0100000 ^ 1000110 -> 1100110 = 102
借用百度百科上的一段话code
二进制是计算技术中普遍采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”。
二进制自己就是为2这个数字而使用的,因此说这道面试题直指二进制的使用是没错的。2的n次方则就是blog
n | 公式 | 结果 |
---|---|---|
1 | 2 | 2 |
2 | 2x2 | 4 |
3 | 2x2x2 | 8 |
4 | 2x2x2x2 | 16 |
换算成二进制的表格是
n | 公式 | 结果 |
---|---|---|
1 | 2 | 000010 |
2 | 2x2 | 000100 |
3 | 2x2x2 | 001000 |
4 | 2x2x2x2 | 010000 |
由此看出2的n次方的二进制最高位是1,其他补0,(n&(n-1))==0 而且 n> 0 的状况下一定是2的n次方,为何要-1呢?在二进制中每一位必须都不相同&后才会得出0,上述已经讲解了&的运算结果。例如十进制的16
16 & (16 - 1) = 010000 & (001111) = 0
不要纠结(n&(n-1))==0 这个公式是怎么来的,做为程序员,我感受应该把更多时间放到反推上面来,去应证这个公式的正确性。
验证是不是2的n次方,笨的方法就是一直除2,除到最后等于0则就是2的次方,因此公式如上
若是是2个二进制进行运算时,计算机会统一位数,例如
01 011 <------> 001 011
计算机会将01自动补一位为001去方便运算。
在二进制中,第一位为1的是负数,0是正数。若是没有补零的状况下
10000000000 01111111111
虽然计算后也是0,但它并非2的n次方,由于第一组二进制是负数。
由上述题补充的另一道题
给定任意数,计算是2的几回方?
function power($number){ if ($number < 0) { return false; } if (($number & ($number - 1)) == 0) { // 数学很差的,就看下面的方法 // $number = decbin($number); // return (mb_strlen($number)-1); // 数学能够的就看下面的方法 return floor(log($number,2)); } else { return false; } }
感谢你看到这里,我也是文中提起的没好好学基础的一名程序员,但当你看到我这篇文章后,但愿你也能够提起精神,去重温下基础,对你将来的职业生涯会起做用的。本章内容纯属本身理解,若有出入,请大佬们监督批评,谢谢🙏