64,637
社区成员
发帖
与我相关
我的任务
分享
1、编译期判断一个正数是否为素数?
由于IsPrimer_impl 特化的版本处理不好,因此目前只能接受500以下的素数,
希望高手帮我提高上限
// 辅助类
template <int value, int index>
struct IsPrimer_impl
{
enum {IsExceed = (index * index > value) ? true : false};
enum {IsDivideExact = (value % index == 0) ? true : false};
enum {result = (IsExceed ? true : (IsDivideExact ? false : IsPrimer_impl<value, index + 1>::result))};
};
// 这里的终止操作处理的不好
template <int value>
struct IsPrimer_impl<value, value>
{
enum {result = true};
};
// result为true,表示value为素数
template <int value>
struct IsPrimer
{
enum {result = IsPrimer_impl<value, 2>::result};
};
template <>
struct IsPrimer<1>
{
enum {result = false};
};
// 测试
int main()
{
// 超过499就会出现错误(VS2008)
cout << IsPrimer<2>::result << endl;
cout << IsPrimer<3>::result << endl;
cout << IsPrimer<40>::result << endl;
cout << IsPrimer<51>::result << endl;
return 0;
}
2、将赋值运算符私有化时,为什么有人将返回值类型定义为void?
这样做有什么用意吗?
3、boost库中any_cast的实现,为什么调用指针版本来完成?
// 转型,通过指针版本完成具体动作
template <class T>
T any_cast(any& operand)
{
const T* result = any_cast<T>(&operand);
if (result == NULL)
throw bad_any_cast();
return *result;
}
template <class T>
T* any_cast(any* operand)
{
return operand && (operand->type() == typeid(T)) ?
&static_cast<holder<T> *>(operand->content)->held : 0;
}
#include<iostream>
using namespace std;
template<bool IsDivideExact,bool IsExceed,int value,int index> struct IsPrimer_impl;
/*
如果整除,必定不是素数;停止模板推导
*/
template<bool IsExceed,int value,int index>
struct IsPrimer_impl<true,IsExceed,value,index>{
enum { result=0 };
};
/*
如果不整除,且index*index>value,必定是素数;停止模板推导
*/
template<int value,int index>
struct IsPrimer_impl<false,true,value,index>{
enum { result=1 };
};
/*
注意,index初值是3,每次递增2,即只考虑奇数。
*/
template<int value,int index>
struct IsPrimer_impl<false,false,value,index>{
enum { result=IsPrimer_impl< (0==value%index), (index*index>value),value,index+2>::result };
};
/*
value>=2
*/
template <int value>
struct IsPrimer
{
enum {result =(value==2) || IsPrimer_impl<(0==value%2),(2*2>value),value, 3>::result};
};
void main(){
cout << IsPrimer<1000*1000*1000>::result << endl;
cout << IsPrimer<2>::result << endl;
cout << IsPrimer<7>::result << endl;
cout << IsPrimer<991*991>::result << endl;
//cout << IsPrimer<997*997>::result << endl;//在VS2008下会导致错误,原因也是超出模板嵌套定义的上限
}
既然无法突破上限,那么在本例中,这是否意味着,要想提高所能处理数的上限,就必须设法减少处理过程中所使用的“空间”,正如楼上用素数集代替自然数集。
#include <iostream>
#include <iomanip>
using namespace std;
#include "prime10000.h"
#define PRINT(N) cout << setw(20) << N << " " << primality<N>::value << endl
size_t const template_recurrsion_limit = 1024 - 1;
// Undetermined - primary algorithm
template <unsigned long long int N, unsigned long long int I = 1,
bool = false, bool = false>
struct primality
{
enum
{
factor = nth_prime<I>::value,
composite = factor*factor <= N && 0 == N%factor,
value = primality<N, (I<template_recurrsion_limit?I+1:0),
(factor*factor>N), composite>::value
};
};
// Prime number
template <unsigned long long int N, unsigned long long int I>
struct primality <N, I, true, false> { enum { value = 1 }; };
// Composite number
template <unsigned long long int N, unsigned long long int I>
struct primality <N, I, false, true> { enum { value = 0 }; };
// Prime number and composite number - logical error
template <unsigned long long int N, unsigned long long int I>
struct primality <N, I, true, true>;
// Uncovered cases
// Let n = template_recurrsion_limit defined above
// and P = the nth prime number
// and S = P * P
// and B = multipulication of the first n prime numbers
// then, N MUST be one of :
// [1] N in [2, S], N MUST be a prime number
// [2] N in (S, B], primality is undetermined
// if N is a composite number, its smallest prime factor
// MUST be great than S
// [3] N in (B,inf), impossible due to machine limit
template <unsigned long long int N, bool P, bool C>
struct primality <N, 0, P, C>
{
enum
{
prime = nth_prime<template_recurrsion_limit>::value,
value = N <= prime*prime ? 1 : 2
};
};
// Zero-divisor
template <unsigned long long int I, bool P, bool C>
struct primality <0, I, P, C> { enum { value = 0 }; };
// Units
template <unsigned long long int I, bool P, bool C>
struct primality <1, I, P, C> { enum { value = 0 }; };
int main (int, char**)
{
cout << setw(20) << "Number" << " Primality" << endl;
PRINT( 0ull);
PRINT( 1ull);
PRINT( 2ull);
PRINT( 3ull);
PRINT( 40ull);
PRINT( 51ull);
PRINT( 499ull);
PRINT( 500ull);
PRINT( 1000ull);
PRINT( 1024ull);
PRINT( 1025ull);
PRINT( 2000ull);
PRINT( 2001ull);
PRINT( 2003ull);
PRINT( 20129ull);
PRINT( 20139ull);
PRINT( 20149ull);
PRINT( 104728ull);
PRINT( 104729ull);
// Below are all prime numbers
PRINT( 16769023ull);
PRINT( 1073676287ull);
PRINT( 1125899839733759ull);
PRINT( 18014398241046527ull);
PRINT( 18014398777917439ull);
PRINT( 32361122672259149ull);
// This is the largest prime number I can find within my machine limit
// largest unsigned long long int = 18446744073709551615ull
PRINT(2305843009213693951ull);
return 0;
}
template <unsigned long long int> struct nth_prime; // We never come here
template <> struct nth_prime < 1> { enum { value = 2 }; };
template <> struct nth_prime < 2> { enum { value = 3 }; };
template <> struct nth_prime < 3> { enum { value = 5 }; };
template <> struct nth_prime < 4> { enum { value = 7 }; };
template <> struct nth_prime < 5> { enum { value = 11 }; };
template <> struct nth_prime < 6> { enum { value = 13 }; };
template <> struct nth_prime < 7> { enum { value = 17 }; };
template <> struct nth_prime < 8> { enum { value = 19 }; };
template <> struct nth_prime < 9> { enum { value = 23 }; };
template <> struct nth_prime < 10> { enum { value = 29 }; };
template <> struct nth_prime < 11> { enum { value = 31 }; };
template <> struct nth_prime < 12> { enum { value = 37 }; };
template <> struct nth_prime < 13> { enum { value = 41 }; };