⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zprime.c

📁 Calc Software Package for Number Calc
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * zprime - rapid small prime routines * * Copyright (C) 1999  Landon Curt Noll * * Calc is open software; you can redistribute it and/or modify it under * the terms of the version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * Calc is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General * Public License for more details. * * A copy of version 2.1 of the GNU Lesser General Public License is * distributed with calc under the filename COPYING-LGPL.  You should have * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA. * * @(#) $Revision: 29.3 $ * @(#) $Id: zprime.c,v 29.3 2006/05/20 08:43:55 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/zprime.c,v $ * * Under source code control:	1994/05/29 04:34:36 * File existed as early as:	1994 * * chongo <was here> /\oo/\	http://www.isthe.com/chongo/ * Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/ */#include "zmath.h"#include "prime.h"#include "jump.h"#include "config.h"#include "zrand.h"#include "have_const.h"/* * When performing a probabilistic primality test, check to see * if the number has a factor <= PTEST_PRECHECK. * * XXX - what should this value be?  Perhaps this should be a function *	 of the size of the text value and the number of tests? */#define PTEST_PRECHECK ((FULL)101)/* * product of primes that fit into a long */static CONST FULL pfact_tbl[MAX_PFACT_VAL+1] = {    1, 1, 2, 6, 6, 30, 30, 210, 210, 210, 210, 2310, 2310, 30030, 30030,    30030, 30030, 510510, 510510, 9699690, 9699690, 9699690, 9699690,    223092870, 223092870, 223092870, 223092870, 223092870, 223092870#if FULL_BITS == 64    , U(6469693230), U(6469693230), U(200560490130), U(200560490130),    U(200560490130), U(200560490130), U(200560490130), U(200560490130),    U(7420738134810), U(7420738134810), U(7420738134810), U(7420738134810),    U(304250263527210), U(304250263527210), U(13082761331670030),    U(13082761331670030), U(13082761331670030), U(13082761331670030),    U(614889782588491410), U(614889782588491410), U(614889782588491410),    U(614889782588491410), U(614889782588491410), U(614889782588491410)#endif};/* * determine the top 1 bit of a 8 bit value: * *	topbit[0] == 0 by convention *	topbit[x] gives the highest 1 bit of x */static CONST unsigned char topbit[256] = {    0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};/* * integer square roots of powers of 2 * * isqrt_pow2[x] == (int)(sqrt(2 to the x power))	      (for 0 <= x < 64) * * We have enough table entries for a FULL that is 64 bits long. */static CONST FULL isqrt_pow2[64] = {    1, 1, 2, 2, 4, 5, 8, 11,					/*  0 ..  7 */    16, 22, 32, 45, 64, 90, 128, 181,				/*  8 .. 15 */    256, 362, 512, 724, 1024, 1448, 2048, 2896,			/* 16 .. 23 */    4096, 5792, 8192, 11585, 16384, 23170, 32768, 46340,	/* 24 .. 31 */    65536, 92681, 131072, 185363,				/* 32 .. 35 */    262144, 370727, 524288, 741455,				/* 36 .. 39 */    1048576, 1482910, 2097152, 2965820,				/* 40 .. 43 */    4194304, 5931641, 8388608, 11863283,			/* 44 .. 47 */    16777216, 23726566, 33554432, 47453132,			/* 48 .. 51 */    67108864, 94906265, 134217728, 189812531,			/* 52 .. 55 */    268435456, 379625062, 536870912, 759250124,			/* 56 .. 59 */    1073741824, 1518500249, 0x80000000, 0xb504f333		/* 60 .. 63 */};/* * static functions */static FULL fsqrt(FULL v);		/* quick square root of v */static long pix(FULL x);		/* pi of x */static FULL small_factor(ZVALUE n, FULL limit);	  /* factor or 0 *//* * Determine if a value is a small (32 bit) prime * * Returns: *	1	z is a prime <= MAX_SM_VAL *	0	z is not a prime <= MAX_SM_VAL *	-1	z > MAX_SM_VAL */FLAGzisprime(ZVALUE z){	FULL n;				/* number to test */	FULL isqr;			/* factor limit */	CONST unsigned short *tp;	/* pointer to a prime factor */	z.sign = 0;	if (zisleone(z)) {		return 0;	}	/* even numbers > 2 are not prime */	if (ziseven(z)) {		/*		 * "2 is the greatest odd prime because it is the least even!"		 *					- Dr. Dan Jurca	 1978		 */		return zisabstwo(z);	}	/* ignore non-small values */	if (zge32b(z)) {		return -1;	}	/* we now know that we are dealing with a value 0 <= n < 2^32 */	n = ztofull(z);	/* lookup small cases in pr_map */	if (n <= MAX_MAP_VAL) {		return (pr_map_bit(n) ? 1 : 0);	}	/* ignore Saber-C warning #530 about empty for statement */	/*	  ok to ignore in proc zisprime */	/* a number >=2^16 and < 2^32 */	for (isqr=fsqrt(n), tp=prime; (*tp <= isqr) && (n % *tp); ++tp) {	}	return ((*tp <= isqr && *tp != 1) ? 0 : 1);}/* * Determine the next small (32 bit) prime > a 32 bit value. * * given: *	z		search point * * Returns: *	0	next prime is 2^32+15 *	1	abs(z) >= 2^32 *	smallest prime > abs(z) otherwise */FULLznprime(ZVALUE z){	FULL n;			/* search point */	z.sign = 0;	/* ignore large values */	if (zge32b(z)) {		return (FULL)1;	}	/* deal a search point of 0 or 1 */	if (zisabsleone(z)) {		return (FULL)2;	}	/* deal with returning a value that is beyond our reach */	n = ztofull(z);	if (n >= MAX_SM_PRIME) {		return (FULL)0;	}	/* return the next prime */	return next_prime(n);}/* * Compute the next prime beyond a small (32 bit) value. * * This function assumes that 2 <= n < 2^32-5. * * given: *	n		search point */FULLnext_prime(FULL n){	CONST unsigned short *tp;	/* pointer to a prime factor */	CONST unsigned char *j;		/* current jump increment */	int tmp;	/* find our search point */	n = ((n & 0x1) ? n+2 : n+1);	/* if we can just search the bit map, then search it */	if (n <= MAX_MAP_PRIME) {		/* search until we find a 1 bit */		while (pr_map_bit(n) == 0) {			n += (FULL)2;		}	/* too large for our table, find the next prime the hard way */	} else {		FULL isqr;		/* factor limit */		/*		 * Our search for a prime may cause us to increment n over		 * a perfect square, but never two perfect squares.  The largest		 * prime gap <= 2614941711251 is 651.  Shanks conjectures that		 * the largest gap below P is about ln(P)^2.		 *		 * The value fsqrt(n)^2 will always be the perfect square		 * that is <= n.  Given the smallness of prime gaps we will		 * deal with, we know that n could carry us across the next		 * perfect square (fsqrt(n)+1)^2 but not the following		 * perfect square (fsqrt(n)+2)^2.		 *		 * Now the factor search limit for values < (fsqrt(n)+2)^2		 * is the same limit for (fsqrt(n)+1)^2; namely fsqrt(n)+1.		 * Therefore setting our limit at fsqrt(n)+1 and never		 * bothering with it after that is safe.		 */		isqr = fsqrt(n)+1;		/*		 * If our factor limit is even, then we can reduce it to		 * the next lowest odd value.  We already tested if n		 * was even and all of our remaining potential factors		 * are odd.		 */		if ((isqr & 0x1) == 0) {			--isqr;		}		/*		 * Skip to next value not divisible by a trivial prime.		 */		n = firstjmp(n, tmp);		j = jmp + jmpptr(n);		/*		 * Look for tiny prime factors of increasing n until we		 * find a prime.		 */		do {			/* ignore Saber-C warning #530 - empty for statement */			/*	  ok to ignore in proc next_prime */			/* XXX - speed up test for large n by using gcds */			/* find a factor, or give up if not found */			for (tp=JPRIME; (*tp <= isqr) && (n % *tp); ++tp) {			}		} while (*tp <= isqr && *tp != 1 && (n += nxtjmp(j)));	}	/* return the prime that we found */	return n;}/* * Determine the previous small (32 bit) prime < a 32 bit value * * given: *	z		search point * * Returns: *	1	abs(z) >= 2^32 *	0	abs(z) <= 2 *	greatest prime < abs(z) otherwise */FULLzpprime(ZVALUE z){	CONST unsigned short *tp;	/* pointer to a prime factor */	FULL isqr;			/* isqrt(z) */	FULL n;				/* search point */	CONST unsigned char *j;		/* current jump increment */	int tmp;	z.sign	= 0;	/* ignore large values */	if (zge32b(z)) {		return (FULL)1;	}	/* deal with special case small values */	n = ztofull(z);	switch ((int)n) {	case 0:	case 1:	case 2:		/* ignore values <= 2 */		return (FULL)0;	case 3:		/* 3 returns the only even prime */		return (FULL)2;	}	/* deal with values above the bit map */	if (n > NXT_MAP_PRIME) {		/* find our search point */		n = ((n & 0x1) ? n-2 : n-1);		/* our factor limit - see next_prime for why this works */		isqr = fsqrt(n)+1;		if ((isqr & 0x1) == 0) {			--isqr;		}		/*		 * Skip to previous value not divisible by a trivial prime.		 */		tmp = jmpindxval(n);		if (tmp >= 0) {			/* find next value not divisible by a trivial prime */			n += tmp;			/* find the previous jump index */			j = jmp + jmpptr(n);			/* jump back */			n -= prevjmp(j);		/* already not divisible by a trivial prime */		} else {			/* find the current jump index */			j = jmp + jmpptr(n);		}		/* factor values until we find a prime */		do {			/* ignore Saber-C warning #530 - empty for statement */			/*	  ok to ignore in proc zpprime */			/* XXX - speed up test for large n by using gcds */			/* find a factor, or give up if not found */			for (tp=prime; (*tp <= isqr) && (n % *tp); ++tp) {			}		} while (*tp <= isqr && *tp != 1 && (n -= prevjmp(j)));	/* deal with values within the bit map */	} else if (n <= MAX_MAP_PRIME) {		/* find our search point */		n = ((n & 0x1) ? n-2 : n-1);		/* search until we find a 1 bit */		while (pr_map_bit(n) == 0) {			n -= (FULL)2;		}	/* deal with values that could cross into the bit map */	} else {		/* MAX_MAP_PRIME < n <= NXT_MAP_PRIME returns MAX_MAP_PRIME */		return MAX_MAP_PRIME;	}	/* return what we found */	return n;}/* * Compute the number of primes <= a ZVALUE that can fit into a FULL * * given: *	z		compute primes <= z * * Returns: *	-1	error *	>=0	number of primes <= x */longzpix(ZVALUE z){	/* pi(<0) is always 0 */	if (zisneg(z)) {		return (long)0;	}	/* firewall */	if (zge32b(z)) {		return (long)-1;	}	return pix(ztofull(z));}/* * Compute the number of primes <= a ZVALUE * * given: *	x		value of z * * Returns: *	-1	error *	>=0	number of primes <= x */static longpix(FULL x){	long count;			/* pi(x) */	FULL top;			/* top of the range to test */	CONST unsigned short *tp;	/* pointer to a tiny prime */	FULL i;	/* compute pi(x) using the 2^8 step table */	if (x <= MAX_PI10B) {		/* x within the prime table, so use it */		if (x < MAX_MAP_PRIME) {			/* firewall - pix(x) ==0 for x < 2 */			if (x < 2) {				count = 0;			} else {				/* determine how and where we will count */				if (x < 1024) {					count = 1;					tp = prime;				} else {					count = pi10b[x>>10];					tp = prime+count-1;				}				/* count primes in the table */				while (*tp++ <= x) {					++count;				}			}		/* x is larger than the prime table, so count the hard way */		} else {			/* case: count down from pi18b entry to x */			if (x & 0x200) {				top = (x | 0x3ff);				count = pi10b[(top+1)>>10];				for (i=next_prime(x); i <= top;				     i=next_prime(i)) {					--count;				}			/* case: count up from pi10b entry to x */			} else {				count = pi10b[x>>10];				for (i=next_prime(x&(~0x3ff));				     i <= x; i = next_prime(i)) {					++count;				}			}		}	/* compute pi(x) using the 2^18 interval table */	} else {		/* compute sum of intervals up to our interval */		for (count=0, i=0; i < (x>>18); ++i) {			count += pi18b[i];		}		/* case: count down from pi18b entry to x */		if (x & 0x20000) {			top = (x | 0x3ffff);			count += pi18b[i];			if (top > MAX_SM_PRIME) {				if (x < MAX_SM_PRIME) {					for (i=next_prime(x); i < MAX_SM_PRIME;					     i=next_prime(i)) {						--count;					}					--count;				}			} else {				for (i=next_prime(x); i<=top; i=next_prime(i)) {					--count;				}			}		/* case: count up from pi18b entry to x */		} else {			for (i=next_prime(x&(~0x3ffff));			     i <= x; i = next_prime(i)) {				++count;			}		}	}	return count;}/* * Compute the smallest prime factor < limit * * given: *	n		number to factor *	zlimit		ending search point *	res		factor, if found, or NULL * * Returns: *	-1	error, limit >= 2^32 *	0	no factor found, res is not changed *	1	factor found, res (if non-NULL) is smallest prime factor

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -