二进制思路
首先有如下两个等式:
2. \(5^{2^{(n+1)}}=(5^2)^{2^{n}}\)
对于二进制,我们不需要将其转换为二进制,只需将指数n&1
即可判断其末位是否为1 。
完成一次判断后,将n右移一位n>>=1
再判断新的末尾即可判断每一位是1或者是2 。
对于指数中的\(2^n\)与\(2^{(n+1)}\),也不需要单独计算,只需每次将底数平方即可(依据公式2)。
初始化
计算\(5^3\)
用res=1
记录累乘的结果。
核心逻辑
判断指数3的末位如为1,res更新为res*5
,等价于$ 5^{( 1 * 2^0)} $ 。
(假如此时判断末位为0,则跳过后半句,执行更新底数) 。
更新底数5为5^2
指数3右移一位变为\((01)_2\)
循环执行上述部分直到指数<=0 。
//exp为指数,x为底数
double res=1.0;while(exp>0){if(exp&1){res*=x;}x*=x;exp>>=1;}
指数折半的思路
对于\(2^7\)我们可以表示为:
\(2^7=2 * 2^6 =2 * (4 ^3)\)而\(4^3=4 * (16^1)\)
同理对于\(3^6\)可以表示为:
\(3^6=(9^3)=9 * (18^1)\)
得到规律:指数为偶数时,指数直接折半,底数平方。
指数为奇数时,先拆一个底数到外面,再折半指数,底数平方
代码如下:
//exp为指数,x为底数
double res=1.0;
while(exp>0){if(exp&1){//如果指数为奇数,拆一个底数与其相乘res*=x;}//底数平方x*=x;//指数折半exp>>=1;}
我们发现两种思路代码完全一致,仅仅是理解方式上有所不同。