让C++编译器算素数

写一个计算素数的小程序不难,如果要求利用C++模板元编程的机制在编译期计算素数呢?

我探索了一下,有兴趣的可以看下面的代码

下面的例子利用编译期运算已经把 [0, 255] 这个区间内256个数字是否是素数的结果放在静态数组IS_PRIME_NUM中了

编译时通过修改宏SS和NN的值(比如加编译选项-DSS=1000 -DNN=9)可以修改这个区间为[SS, SS+(1<<NN)-1]

它的编译比较漫长(尤其是把NN设得更大时)

但是程序编译成功后运算起来很快,因为计算素数的运算都放在编译期去完成了

template <bool B, typename X, typename Y>
struct get_type {
    typedef X type;
};

template <typename X, typename Y>
struct get_type<false, X, Y> {
    typedef Y type;
};

struct not_exist {
    static const bool is_exist = false;
};

template <unsigned N, unsigned START, unsigned LEN>
struct find_divisor {
    static const bool is_exist = find_divisor<N, START, LEN/2>::is_exist
        || get_type< START*START<=N, find_divisor<N, START+(LEN/2), LEN-(LEN/2)>, not_exist >::type::is_exist;
};

template <unsigned N, unsigned START>
struct find_divisor<N, START, 1> {
    static const bool is_exist = (N % START == 0);
};

template <unsigned N>
struct is_prime_number {
    static const bool result = ! find_divisor<N, 2, N-2>::is_exist;
};

template <> struct is_prime_number<2> { static const bool result = true; };
template <> struct is_prime_number<1> { static const bool result = false; };
template <> struct is_prime_number<0> { static const bool result = false; };

#define POW2_0(x) is_prime_number<x>::result,
//for i in {0..15}; do echo "#define POW2_$((i+1))(x) POW2_$i(x) POW2_$i(x+$((1<<i)))"; done
#define POW2_1(x) POW2_0(x) POW2_0(x+1)
#define POW2_2(x) POW2_1(x) POW2_1(x+2)
#define POW2_3(x) POW2_2(x) POW2_2(x+4)
#define POW2_4(x) POW2_3(x) POW2_3(x+8)
#define POW2_5(x) POW2_4(x) POW2_4(x+16)
#define POW2_6(x) POW2_5(x) POW2_5(x+32)
#define POW2_7(x) POW2_6(x) POW2_6(x+64)
#define POW2_8(x) POW2_7(x) POW2_7(x+128)
#define POW2_9(x) POW2_8(x) POW2_8(x+256)
#define POW2_10(x) POW2_9(x) POW2_9(x+512)
#define POW2_11(x) POW2_10(x) POW2_10(x+1024)
#define POW2_12(x) POW2_11(x) POW2_11(x+2048)
#define POW2_13(x) POW2_12(x) POW2_12(x+4096)
#define POW2_14(x) POW2_13(x) POW2_13(x+8192)
#define POW2_15(x) POW2_14(x) POW2_14(x+16384)
#define POW2_16(x) POW2_15(x) POW2_15(x+32768)

#define GEN_(S, N) POW2_##N(S)
#define GEN(S, N) GEN_(S, N)

#ifndef SS
#define SS 0
#endif

#ifndef NN
#define NN 8
#endif

static const bool IS_PRIME_NUM[] = {
    GEN((SS), NN)
};

#include <cstdio>

int main() {
    printf("[%u, %u]\n", SS, (SS)+(1<<NN)-1);
    for(unsigned i = 0; i < sizeof(IS_PRIME_NUM)/sizeof(IS_PRIME_NUM[0]); i++) {
        if(IS_PRIME_NUM[i]) {
            printf("%u\n", (SS)+i);
        }
    }
    return 0;
}

转载于:https://my.oschina.net/2bit/blog/392822

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值