【C语言判断给定的数是否为质数的函数】

C语言判断给定的数是否为质数的函数

质数定义

质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。

判断一个数是否为质数的方法

  1. 对于质数p,从2开始一直到p-1,每个数都试除一下,如果有整除的情况,则说明p不是质数,否则说明p是质数。
  2. 实际上,可以不用一直到p-1,到p的平方根就可以,如果用2到p的平方根之间的所有整数去试除,均无法整除,则p为质数。这样可以减少试除的次数,提高判断效率!!!
  3. 模运算mod,即求余数运算,操作符%,如果 n % i == 0 则说明n除以i的余数为0,即n能被i整除,i是n的因数,i大于1,则n不是质数。
  4. 编码时,判断给定的整数n,从i=2开始,直到ii <= n(ii==n,则i是n的平方根),i每次增加一,循环判断 n%i == 0,如果成立返回0,说明n不是质数,如果循环顺利结束,则说明n是质数,返回1。

代码如下:

/* filename: prime.c */
#include <stdio.h>

/* compile : gcc prime.c -o prime
       run : ./prime               */

/* first version */
int
is_prime (int n)
{
  if (n < 2) return 0;
  if (n == 2) return 1;
  for (int i = 2; i*i <= n; i++)
    if (n % i == 0) return 0;
  return 1;
}

/* get prime frome 1 to n */
void
get_prime (int n)
{
  printf ("Prime from 1 to %d :\n", n);
  for (int i = 0; i < n; i++)
    //if (1 == is_prime (i)) printf ("%d ", i);
    if (is_prime(i)) printf ("%d ", i);
  printf ("\n");
}

/**/
int
main (int argc, char *argv[])
{
  get_prime (100);
  return 0;
}
/* --(:-O-:)-- */

编译运行,结果如下:

songvm@ubuntu:~/works/xdn$ gcc prime.c -o prime
songvm@ubuntu:~/works/xdn$ ./prime
Prime from 1 to 100 :
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 

is_prime函数第二个版本

  1. 以上的效果可以!改造一下,可以判断大一点儿的整数,参数改为无符号长整型!!!
  2. 将函数is_prime重写,提高效率,分成四种情况:
  3. 条件一:0和1不是质数!!!
  4. 条件二:2是质数!!!
  5. 条件三:能被2整除的数(偶数)不是质数,2除外(条件二)!!!
  6. 条件四:能被大于等于3的奇数整除的数不是质数!!!
  7. 不满足上述四个条件则是质数!!!
  8. 依次输出1 - 100,1 - 1000,1 - 10000,1 - 100000区间的质数数量

代码如下:

/* filename: prime.c */
#include <stdio.h>

/* compile : gcc prime.c -o prime
       run : ./prime               */

/**/
typedef unsigned long ulong;

/* second version */
ulong
is_prime (ulong n)
{
  if (n < 2) return 0;      //0,1 not a prime
  if (n == 2) return 1;     //2 is a prime
  if (n % 2 == 0) return 0; //Even numbers not a prime
  for (ulong i = 3; i*i <= n; i = i + 2)
    if (n % i == 0) return 0; //Divided by odd numbers not a prime
  return 1;
}

/* test, get prime count 1 to 100000 */
void
test_get_prime (void)
{
  int count = 0;
  for (ulong i = 1; i < 100000; i++)
    {
      if (is_prime(i)) count++;
      if (i == 100)
	printf ("1 - 100 : %d\n", count);
      else if (i == 1000)
	printf ("1 - 1000 : %d\n", count);
      else if (i == 10000)
	printf ("1 - 10000 : %d\n", count);
    }
  printf ("1 - 100000 : %d\n", count);
}

/**/
int
main (int argc, char *argv[])
{
  test_get_prime ();
  return 0;
}
/* --(:-O-:)-- */

编译运行,结果如下:

songvm@ubuntu:~/works/xdn/woo$ gcc prime.c -o prime
songvm@ubuntu:~/works/xdn/woo$ ./prime
1 - 100 : 25
1 - 1000 : 168
1 - 10000 : 1229
1 - 100000 : 9592

测试大的整数区间

  • 再测试一下,找出从0xFFFFFF01到0xFFFFFFFF之间的质数。(16进制很有用呀!)
  • 用16进制写长整型数,判断一个大一点儿的整数区间!!!
    代码如下:
/* filename: prime.c */
#include <stdio.h>

/* compile : gcc prime.c -o prime
       run : ./prime               */

/**/
typedef unsigned long ulong;

/* second version */
ulong
is_prime (ulong n)
{
  if (n < 2) return 0;      //0,1 not a prime
  if (n == 2) return 1;     //2 is a prime
  if (n % 2 == 0) return 0; //Even numbers not a prime
  for (ulong i = 3; i*i <= n; i = i + 2)
    if (n % i == 0) return 0; //Divided by odd numbers not a prime
  return 1;
}

/* test, get prime from 0xFFFFFF01 to 0xFFFFFFFF */
void
test_get_prime (void)
{
  int count = 0;
  ulong uf = 0xFFFFFF01;
  ulong ut = 0xFFFFFFFF;
  printf ("Prime from %lu to %lu :\n", uf, ut);
  for (ulong i = uf; i <= ut; i = i + 2)
    {
      if (is_prime(i))
	{
	  count++;
	  printf ("%d, %lX, %lu\n", count, i, i);
	}
    }
}

/**/
int
main (int argc, char *argv[])
{
  test_get_prime ();
  return 0;
}
/* --(:-O-:)-- */

编译运行,结果如下:

songvm@ubuntu:~/works/xdn$ gcc prime.c -o prime
songvm@ubuntu:~/works/xdn$ ./prime
Prime from 4294967041 to 4294967295 :
1, FFFFFF2F, 4294967087
2, FFFFFF47, 4294967111
3, FFFFFF67, 4294967143
4, FFFFFF79, 4294967161
5, FFFFFF95, 4294967189
6, FFFFFF9D, 4294967197
7, FFFFFFBF, 4294967231
8, FFFFFFEF, 4294967279
9, FFFFFFFB, 4294967291
  1. test_get_prime函数中,for循环每次增加2,只测试奇数,偶数不用测试,因为它不是质数!!!
  2. 在254个数中间找到了9个质数,是不是数越大,质数的分布就越稀薄了?!

用第一个版本验证

  • 数太大将整型改为无符号长整型!!!
    代码如下:
/* filename: prime.c */
#include <stdio.h>

/* compile : gcc prime.c -o prime
       run : ./prime               */

/**/
typedef unsigned long ulong;

/* first version */
int
is_prime (ulong n)
{
  if (n < 2) return 0;
  if (n == 2) return 1;
  for (ulong i = 2; i*i <= n; i++)
    if (n % i == 0) return 0;
  return 1;
}

/* test, get prime from 0xFFFFFF01 to 0xFFFFFFFF */
void
test_get_prime (void)
{
  int count = 0;
  ulong uf = 0xFFFFFF01;
  ulong ut = 0xFFFFFFFF;
  printf ("Prime from %lu to %lu :\n", uf, ut);
  for (ulong i = uf; i <= ut; i = i + 2)
    {
      if (is_prime(i))
	{
	  count++;
	  printf ("%d, %lX, %lu\n", count, i, i);
	}
    }
}

/**/
int
main (int argc, char *argv[])
{
  test_get_prime ();
  return 0;
}
/* --(:-O-:)-- */

编译运行,结果一致

songvm@ubuntu:~/works/xdn/woo$ ./prime
Prime from 4294967041 to 4294967295 :
1, FFFFFF2F, 4294967087
2, FFFFFF47, 4294967111
3, FFFFFF67, 4294967143
4, FFFFFF79, 4294967161
5, FFFFFF95, 4294967189
6, FFFFFF9D, 4294967197
7, FFFFFFBF, 4294967231
8, FFFFFFEF, 4294967279
9, FFFFFFFB, 4294967291

最后测试一下,统计1到10亿之间共有多少个质数

代码如下:

/* filename: prime.c */
#include <stdio.h>

/* compile : gcc prime.c -o prime
       run : ./prime               */

/**/
typedef unsigned long ulong;

/* second version */
ulong
is_prime (ulong n)
{
  if (n < 2) return 0;      //0,1 not a prime
  if (n == 2) return 1;     //2 is a prime
  if (n % 2 == 0) return 0; //Even numbers not a prime
  for (ulong i = 3; i*i <= n; i = i + 2)
    if (n % i == 0) return 0; //Divided by odd numbers not a prime
  return 1;
}

/* test, get prime count 1 to 1000000000 */
void
test_get_prime (void)
{
  int count = 0;
  for (ulong i = 1; i < 1000000000; i++)
    {
      if (is_prime(i)) count++;
    }
  printf ("1 - 1000000000 : %d\n", count);
}

/**/
int
main (int argc, char *argv[])
{
  test_get_prime ();
  return 0;
}
/* --(:-O-:)-- */

编译运行,结果如下:

songvm@ubuntu:~/works/xdn/woo$ gcc prime.c -o prime
songvm@ubuntu:~/works/xdn/woo$ ./prime
1 - 1000000000 : 50847534

这个程序在我的虚拟机上运行了一个半小时可能还多,因为我用ps -all看到下面结果后,去了一次洗手间,回来再用ps -all才发现看不到prime进程了 😦

0 R  1000   8770   8227 99  80   0 -  1129 -      pts/1    01:23:05 prime
  • 50847534,这个结果和网上搜索到的结果是一致的,谢天谢地!!!
  • 还有更快的方法,就是筛选法,下一步研究一下!同时也核对一下这个数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值