1.欧拉函数
欧拉函数是数论中的一个重要函数。
同时,它也是密码系统不可缺少的极其重要的函数。
-
* 欧拉函数:数论中,对于正整数n,欧拉函数是小于n的数中与n互质的数的数目。
-
* 此函数以其首名研究者欧拉命名(Ruler'so totient function),
-
* 又称为Euler's totient function、φ函数、欧拉商数等
#include<stdio.h>
int eular(int n)
{
int ret=1,i;
for(i=2;i*i<=n;i++){
if(n%i==0){
n/=i;
ret*=i-1;
while(n%i==0){
n/=i;
ret*=i;
}
}
}
if(n>1)
{
ret*=n-1;
}
return ret;
}
int main(void)
{
int i;
for(i=2;i<=100;i++)
{
printf("i=%d eular=%d\n",i,eular(i));
}
return 0;
}
2.最大素因数
Largest prime factor
筛选法原理适用于本程序,但是不需要用数组来存储筛选结果。
本程序参考欧拉函数写成,是采用逐步排除小素数因子最后得到最大素因数的方法。
* 最大素因数—Largest prime factor
*
* The prime factors of 13195 are 5, 7, 13 and 29.
* What is the largest prime factor of the number 600851475143 ?
*
* 这个问题称为"Prime Factorization"(分解质因数),prime factor称为质因子(或素因子)。
* 素数也称为质数,是只能被1和自身整除的整数,不包括1。
*
* 本程序是参考欧拉函数写成的。
* 条件:n>=2
#include<stdio.h>
long maxfact(long n)
{
long ret=2L,i;
while(n%2==0)
n/=2;
for(i=3;i*i<=n;i+=2){
if(n%i==0){
ret=i;
n/=i;
while(n%i==0)
n/=i;
}
}
return (n==1)?ret:n;
}
int main(void)
{
printf("n=%ld maxfact=%ld\n",32L,maxfact(32));
printf("n=%ld maxfact=%ld\n",9L,maxfact(9));
printf("n=%ld maxfact=%ld\n",13195L,maxfact(13195));
printf("n=%ld maxfact=%ld\n",600851475143L,maxfact(600851475143));
return 0;
}
3.Eratosthenes筛选法
Sieve of Eratosthenes
使用埃拉托斯特尼筛选法计算小于100000的素数。
埃拉托斯特尼筛选法是最为知名的产生素数的筛选法,适用于产生最小的N个素数。
该方法的唯一缺点是使用的存储空间大,可以进一步改进。
另外,该算法也不适用于计算某个范围内的全部素数。
筛选法计算小于100000的素数
筛选法求最小的素数序列,原本是不朽的数学家们手工计算的方法,
稍微费点空间,也是适合于计算机进行计算的算法
#include<stdio.h>
#include<math.h>
#define MAX 100
int arr[MAX+1]={0,0,1};
int main(void)
{
int i,j;
int num=0;
for(i=3;i<MAX;i++){
arr[i++]=1;
arr[i]=0;
}
int max=sqrt(MAX);
for(i=3;i<max;i++){
if(arr[i]){
for(j=i+i;j<MAX;j+=i)
arr[j]=0;
}
}
for(i=2;i<MAX;i++){
if(arr[i]){
++num;
printf("%d:%d\n",num,i);
}
}
return 0;
}
4.快速计算素数程序
Wheel factorization
Wheel factorization是一种生成素数方法。
对于大于30的数,只有30n+1,30n+7,30n+11,30n+13,30n+17,30n+19,30n+23,30n+29才可能是素数,这里n>=1。
#include<stdio.h>
#include<math.h>
#define NUM_O_PRIMES 2015
long primes1[NUM_O_PRIMES];
void primes()
{
int base=30,pc=0,column[]={1,7,11,13,17,19,23,29};
int pp=0;
primes1[pp++]=2;
primes1[pp++]=3;
primes1[pp++]=5;
primes1[pp++]=7;
primes1[pp++]=11;
primes1[pp++]=13;
primes1[pp++]=17;
primes1[pp++]=19;
primes1[pp++]=23;
primes1[pp++]=29;
while(pp<NUM_O_PRIMES)
{
if(pc==8)
{
base+=30;
pc=0;
}
long p,q;
p=base+column[pc++];
q=sqrt(p);
int j=3;
while(primes1[j]<=q)
{
if(p%primes1[j]==0)
break;
j++;
}
if(primes1[j]>q)
primes1[pp++]=p;
}
}
int main(void)
{
primes();
int i;
for(i=0;i<NUM_O_PRIMES;i++)
{
printf("%d:%d\n",i+1,primes1[i]);
}
return 0;
}