Placard

来看我的主页~,以后可能不维护BLOG了。

http://euclid.ik8.com

Category
Latest Entries
Latest Comments
Last Messages
Links
Information
Search
Other
Welcome to euclid blog!
  快速整乘方算法
 

  快速整乘方算法
名字起的好象有点夸张了~,跟快排类似的名字,都是O(log(n))的。

double power (double a, int n)
/* 返回a的整数n次幂 */
{
        int mask, len = sizeof (int) * 8 - 1;
        double s = 1.0;

        if (n == 0) return 1.0;
        if (n < 0) {n = -n; a = 1.0 / a;}
        for (mask = 0x4000; len > 0 && !(n & mask); --len, mask >>= 1);
        for (mask = 1; len > 0; --len, mask <<= 1, a *= a)
                if (n & mask) s *= a;

        return s;
}

解释:

    算法极简单,变形 a^n = a^(2^t1+x^t2+...2^tm) = a^(2^t1) * a^(2^t2)... * a^(2^tm).
    例:a^(2^tm) = (((a^2)^2)...)^2,tm次迭代。而n本身已经告诉了我们t1...tm的值,即各位的序号,用位操作可将其挖掘出来。按这个方法手工算一下a^7:
1.  7 = 0000...0111B = 2^0 + 2^1 + 2^2;
2.  a^7 = a^(2^0) * a^(2^1) * a^(2^2)
3.  看出后一项是前项的平方,可用3次迭代a *= a即可。

再解释代码:
    mask就是挖掘n某位的东西,0x4000相当于01000...0(1后14个零),最高位是符号位,在第1个for里右移,第2个for里左移,因为必须听a的,a只能不断累加;len在第一个for里记录n的最高位,在第二个for里仅当循环次数游标;就这些。
 

补:kk的直接移n的完美算法

for (; n; s *= n & 1 ? a : 1.0, a *= a, n >>= 1);

[ 阅读全文 | 回复(3) | 引用通告 | 编辑

  Post  by  欧几里得 发表于 2005-10-29 15:34:00
  Re:快速整乘方算法
  我怀疑用log 然后exp会更快

以下为blog主人的回复:exp是什么?

 

[ 个人主页 | 引用 | 返回 | 删除 | 回复

  Post  by  David(游客)发表评论于2005-10-31 11:36:00
  Re:快速整乘方算法
  是啊,直接用n移就行了。
[ 个人主页 | 引用 | 返回 | 删除 | 回复

  Post  by  euclid发表评论于2005-10-30 19:20:00
  Re:快速整乘方算法
 

mask用得罗嗦了:)

[ 个人主页 | 引用 | 返回 | 删除 | 回复

  Post  by  kaikai(游客)发表评论于2005-10-29 19:54:00

发表评论:

    昵称:
    密码: (游客无须输入密码)
    主页:
    标题:
Power By euclid备忘录
Powered by Oblog.