/* trn.h Thomas R. Nicely 2007.02.09.2300
* http://www.trnicely.net
* GCC 3.04 DJGPP 2.03 GMP 4.01
*
* Freeware copyright (c) 2007 Thomas R. Nicely
* <http://www.trnicely.net>. No warranties expressed or implied.
* Distributed under the terms of the GNU GPL, GNU FDL, and DJGPP
* licenses; see <http://www.gnu.org/licenses/licenses.html> and
* <http://www.delorie.com/djgpp>. Source, binaries, and license
* terms available upon request.
*
* Revised for compatibility with GCC 4.02 and GMP 4.14
* (-std=gnu99) running under GNU/Linux (kernel release
* 2.6.13-15-default, SUSE Linux 10.0 i386) as root.
*
* Header for custom library routines written by Thomas R. Nicely.
* The source code is in trn.c.
*
* If it desired to equate old identifiers (such as _iSignum)
* with newer ones (such as iSignum), define _OLD_IDENTIFIERS_TRN
* BEFORE inclusion of this header.
*
*/
#ifndef _TRN_H_
#define _TRN_H_ 1
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#ifndef __USE_GNU
#define __USE_GNU 1
#endif
#if defined(__WIN32__) || defined(__DJGPP__)
#ifndef __MSDOS__
#define __MSDOS__ 1
#endif
#endif
#if !defined(__dj_include_math_h_) && !defined(_MATH_H)
#include <math.h>
#endif
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <gmp.h>
#undef __OBSL__ /* Output blank screen line (usually at program exit) */
#ifdef __MSDOS__
#define __OBSL__ {printf("\n");}
#include <conio.h>
#else
#define __OBSL__ {printf("\n\n");}
#endif
/**********************************************************************/
/******************** MANIFEST CONSTANTS CORRECTED ********************/
/**********************************************************************/
/* Redefine the manifest constants in math.h to properly implement
long double precision. This fixes an oversight (or a misguided
commitment to 53-bit double precision) in many versions of math.h. */
/* From GNU C 3.04 */
#undef M_E /* e */
#undef M_LOG2E /* log_2(e) */
#undef M_LOG10E /* log_10(e) */
#undef M_LN2 /* ln(2) */
#undef M_LN10 /* ln(10) */
#undef M_PI /* pi */
#undef M_PI_2 /* pi/2 */
#undef M_PI_4 /* pi/4 */
#undef M_1_PI /* 1/pi */
#undef M_2_PI /* 2/pi */
#undef M_2_SQRTPI /* 2/sqrt(pi) */
#undef M_SQRT2 /* sqrt(2) */
#undef M_SQRT1_2 /* sqrt(1/2) */
#undef PI /* in accordance with C99 */
#undef PI2 /* in accordance with C99 */
/* Corrected values are given to 50 decimal places (at least 165-bit
precision). */
#define M_E 2.71828182845904523536028747135266249775724709369996L
#define M_LOG2E 1.44269504088896340735992468100189213742664595415299L
#define M_LOG10E 0.43429448190325182765112891891660508229439700580367L
#define M_LN2 0.69314718055994530941723212145817656807550013436026L
#define M_LN10 2.30258509299404568401799145468436420760110148862877L
#define M_PI 3.14159265358979323846264338327950288419716939937511L
#define M_PI_2 1.57079632679489661923132169163975144209858469968755L
#define M_PI_4 0.78539816339744830961566084581987572104929234984378L
#define M_1_PI 0.31830988618379067153776752674502872406891929148091L
#define M_2_PI 0.63661977236758134307553505349005744813783858296183L
#define M_2_SQRTPI 1.12837916709551257389615890312154517168810125865800L
#define M_SQRT2 1.41421356237309504880168872420969807856967187537695L
#define M_SQRT1_2 0.70710678118654752440084436210484903928483593768847L
/* From B*rland C++ 4.52 */
#undef M_1_SQRTPI /* 1/sqrt(pi) */
#undef M_SQRT_2 /* sqrt(1/2) */
#define M_1_SQRTPI 0.56418958354775628694807945156077258584405062932900L
#define M_SQRT_2 M_SQRT1_2
/* From ... M*cr*s*ft C ? */
#undef M_SQRT3 /* sqrt(3) */
#undef M_TWOPI /* 2*pi */
#undef M_3PI_4 /* 3*pi/4 */
#undef M_SQRTPI /* sqrt(pi) */
#undef M_LOGE /* log_10(e) */
#undef M_IVLN10 /* 1/ln(10) */
#undef M_LOG2_E /* ln(2) */
#undef M_INVLN2 /* 1/ln(2) */
#undef M_LOG2 /* log_10(2) */
#define M_SQRT3 1.73205080756887729352744634150587236694280525381038L
#define M_TWOPI 6.28318530717958647692528676655900576839433879875021L
#define M_3PI_4 2.35619449019234492884698253745962716314787704953133L
#define M_SQRTPI 1.77245385090551602729816748334114518279754945612239L
#define M_LOGE M_LOG10E
#define M_IVLN10 M_LOG10E
#define M_LOG2_E M_LN2
#define M_INVLN2 M_LOG2E
#define M_LOG2 0.30102999566398119521373889472449302676818988146211L
/* Nicely constants */
#undef M_LOG_2_BASE10
#undef M_LOG_E_BASE2
#undef M_LOG_E_BASE10
#undef M_LI2
#undef M_C2
#undef M_C3
#undef M_C4
#undef M_HL2
#undef M_HL3
#undef M_HL4
#undef M_ACC2
#undef M_ACC3
#undef M_ACC4
#undef M_LN2_SQUARED
#undef M_LN2_CUBED
/* The constants M_LI2, M_C2, M_C3, M_C4, M_HL2, M_HL3, M_HL4, M_ACC2,
M_ACC3, and M_ACC4 appear in calculations involving the
Hardy-Littlewood integrals, twin primes, prime triplets, and
prime quadruplets. */
#define M_LOG_2_BASE10 M_LOG2
#define M_LOG_E_BASE2 M_LOG2E
#define M_LOG_E_BASE10 M_LOG10E
#define M_LI2 1.045163780117492784844588889194613136522615578L /* Li(2) */
#define M_C2 0.660161815846869573927812110014555778432623360L /* twins */
#define M_C3 0.635166354604271207206696591272522417342065687L /* trplts */
#define M_C4 0.307494878758327093123354486071076853022178520L /* quads */
#define M_HL2 1.320323631693739147855624220029111556865246721L
#define M_HL3 2.858248595719220432430134660726350878039295593L
#define M_HL4 4.151180863237415757165285561959537515799410019L
#define M_ACC2 2.640647263387478295711248440058223113730493441L
#define M_ACC3 4.287372893578830648645201991089526317058943389L
#define M_ACC4 5.534907817649887676220380749279383354399213359L
#define M_LN2_SQUARED 0.48045301391820142466710252632666497173055295159455L
#define M_LN2_CUBED 0.33302465198892947971885358261173054415612648534861L
/* Long double constants such as, and including those defined in
GNU extensions. */
#undef M_El
#undef M_LOG2El
#undef M_LOG10El
#undef M_LN2l
#undef M_LN10l
#undef M_PIl
#undef M_PI_2l
#undef M_PI_4l
#undef M_1_PIl
#undef M_2_PIl
#undef M_2_SQRTPIl
#undef M_SQRT2l
#undef M_SQRT1_2l
#undef M_1_SQRTPIl
#undef M_SQRT_2l
#undef M_SQRT3l
#undef M_TWOPIl
#undef M_3PI_4l
#undef M_SQRTPIl
#undef M_LOGEl
#undef M_IVLN10l
#undef M_LOG2_El
#undef M_INVLN2l
#undef M_LOG2l
#undef M_LOG_2_BASE10l
#undef M_LOG_E_BASE2l
#undef M_LOG_E_BASE10l
#undef M_LN2_SQUAREDl
#undef M_LN2_CUBEDl
#define M_El M_E
#define M_LOG2El M_LOG2E
#define M_LOG10El M_LOG10E
#define M_LN2l M_LN2
#define M_LN10l M_LN10l
#define M_PIl M_PI
#define M_PI_2l M_PI_2
#define M_PI_4l M_PI_4
#define M_1_PIl M_1_PI
#define M_2_PIl M_2_PI
#define M_2_SQRTPIl M_2_SQRTPI
#define M_SQRT2l M_SQRT2
#define M_SQRT1_2l M_SQRT1_2
#define M_1_SQRTPIl M_1_SQRTPI
#define M_SQRT_2l M_SQRT_2
#define M_SQRT3l M_SQRT3
#define M_TWOPIl M_TWOPI
#define M_3PI_4l M_3PI_4
#define M_SQRTPIl M_SQRTPI
#define M_LOGEl M_LOGE
#define M_IVLN10l M_IVLN10
#define M_LOG2_El M_LOG2_E
#define M_INVLN2l M_INVLN2
#define M_LOG2l M_LOG2
#define M_LOG_2_BASE10l M_LOG2_BASE10
#define M_LOG_E_BASE2l M_LOG_E_BASE2
#define M_LOG_E_BASE10l M_LOG_E_BASE10
#define M_LI2l M_LI2
#define M_LN2_SQUAREDl M_LN2_SQUARED
#define M_LN2_CUBEDl M_LN2_CUBED
/**********************************************************************/
/****************** END MANIFEST CONSTANTS CORRECTED ******************/
/**********************************************************************/
/* Parameters that should have been taken care of by <limits.h>. */
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
#if !defined(LLONG_MAX)
# if defined(LONG_LONG_MAX)
# define LLONG_MAX LONG_LONG_MAX
# else
# define LLONG_MAX 9223372036854775807LL
# endif
#else
# if !defined(LONG_LONG_MAX)
# define LONG_LONG_MAX LLONG_MAX
# endif
#endif
#if !defined(LLONG_MIN)
# if defined(LONG_LONG_MIN)
# define LLONG_MIN LONG_LONG_MIN
# else
# define LLONG_MIN -9223372036854775808LL
# endif
#else
# if !defined(LONG_LONG_MIN)
# define LONG_LONG_MIN LLONG_MIN
# endif
#endif
#if !defined(ULLONG_MAX)
# if defined(ULONG_LONG_MAX)
# define ULLONG_MAX ULONG_LONG_MAX
# else
# define ULLONG_MAX 18446744073709551615ULL
# endif
#else
# if !defined(ULONG_LONG_MAX)
# define ULONG_LONG_MAX ULLONG_MAX
# endif
#endif
/* Miscellaneous defines, including the maximum number of decimal digits
for which mpz_t storage is to be reserved, and the corresponding
maximum number of bits; __MAX_BITS__=ceil(__MAX_DIGITS__/log_10(2)). */
#undef __MAX_DIGITS__
#undef __MAX_BITS__
#define __MAX_DIGITS__ 1001000UL
#define __MAX_BITS__ (3*__MAX_DIGITS__ + __MAX_DIGITS__/3 + 1)
/* Custom gmp routines */
unsigned long long _mpz_get_ull(mpz_t mpz);
void _mpz_set_ull(mpz_t mpz, unsigned long long ull);
long double _mpz_get_ld(mpz_t mpz);
void _mpz_set_ld(mpz_t mpz, long double ld);
int _mpz_cmp_ld(mpz_t mpz, long double ld);
long double _mpz_log10l(mpz_t mpz);
long double _mpz_logl(mpz_t mpz);
void _mpz_powl(mpz_t mpz, long double ldBase,
long double ldExp);
void _mpz_expl(mpz_t mpz, long double ldExp);
#ifdef __i386__
long double _mpf_get_ld(mpf_t mpf);
void _mpf_set_ld(mpf_t mpf, long double ld);
long double __strtold(char *sz, char **ep);
#else
long double _mpf_get_ld2(mpf_t mpf);
void _mpf_set_ld2(mpf_t mpf, long double ld);
#define _mpf_get_ld _mpf_get_ld2
#define _mpf_set_ld _mpf_set_ld2
#define __strtold strtold
#endif
int __mpz_set_str(mpz_t mpz, char *sz, int iBase);
int __mpf_set_str(mpf_t mpf, char *sz, int iBase);
/* Prime number generation and testing */
void vGenPrimes16(void);
int iIsPrime32(unsigned long ulN);
int iIsPrime64(unsigned long long ullN, unsigned long ulMaxDivisor);
int iPrP(mpz_t mpzN, unsigned long ulNMR, unsigned long ulMaxDivisor);
unsigned long ulPrmDiv(mpz_t mpzN, unsigned long ulMaxDivisor);
int iMillerRabin(mpz_t mpzN, unsigned long ulB);
int iLucasSelfridge(mpz_t mpzN);
int iStrongLucasSelfridge(mpz_t mpzN);
int iExtraStrongLucas(mpz_t mpzN, long lB);
/* Functions returning (for x >= 2) Li(x); the Hardy-Littlewood integral
approximations for the counts of twin primes, triplets, and
quadruplets; Riemann's prime counting function R(x); and Riemann's
zeta function. */
long double ldLogInt(long double ldx, long double *ldHL2,
long double *ldHL3, long double *ldHL4);
long double ldLi(long double ldx);
long double ldRPCF(long double ldx);
void vDefineZetaArray(void);
long double ldZeta(long double ldx);
/* String editing */
char *szTrimMWS(char *pch);
char *szTrimTWS(char *pch);
char *szTrimLWS(char *pch);
/* Routines for analyzing prime gap records */
int iRecordValidExt(char *sz);
int iGetGapRecExt(char *szGapRec, FILE *fpIn);
void vGapContExt(char *szContRec, char *szGapRec);
int iGetGapRec(char *szGapRec, FILE *fpIn);
int iRecordValid(char *szRec);
void vGapCont(char *szContRec, char *szGapRec);
/* Miscellaneous routines */
void vFlush(void);
int __iLockMemory(void *MemStartAddress, unsigned long ulBytes);
unsigned long __ulPhysicalMemoryAvailable(void);
int iSignum(long double ldArg);
int _isFile(char *szFileName);
int _isRFile(char *szFileName);
int _isRWFile(char *szFileName);
double lfSeconds2(void);
unsigned long ulSqrt(unsigned long long ull);
void vAtExit(void);
void vSigInt(int iSig);
void _vZeroFile(FILE *fp, char *szName);
/* The GNU munlock function has no direct counterpart in DJGPP;
DOS/W*ndows memory is unlocked when freed, unless it has
been explicitly locked by means of Win32 or raw DPMI calls. */
#ifdef __DJGPP__
#define munlock(pvoid, sizet) 0
#else
#define stricmp(sz1, sz2) strcasecmp(sz1, sz2)
#define strnicmp(sz1, sz2, i) strncasecmp(sz1, sz2, i)
char *strlwr(char *sz);
char *strupr(char *sz);
#endif
#define strcmpi(sz1, sz2) strcasecmp(sz1, sz2)
#define strncmpi(sz1, sz2, i) strncasecmp(sz1, sz2, i)
#undef _iSignum
#define _iSignum iSignum
/* Expression parser for mpz bigints. iEvalExpr and iParseMPZ are
deprecated identifiers. */
int iEvalExprMPZ(mpz_t mpzResult, char *szExpression);
#define iEvalExpr iEvalExprMPZ
#define iParseMPZ iEvalExprMPZ
/**********************************************************************/
/*********************** LONG DOUBLE FUNCTIONS ************************/
/**********************************************************************/
#if defined(__i386__) && defined(__DJGPP__) && (__DJGPP <= 2) \
&& defined(__DJGPP_MINOR__) && (__DJGPP_MINOR__ <= 4)
/* Custom long double routines, implemented in trn.c with inline assembly
specific to the x87 coprocessors. The corresponding intrinsic long
double routines, mandated by C99 and gnu99, appear to be missing
from versions of DJGPP through 2.04. Presumably they will be
supported in ports of GNU C, versions 4.00 and beyond. */
#undef ceill
#undef expl
#undef fabsl
#undef floorl
#undef fmodl
#undef iSignum
#undef logl
#undef log10l
#undef powl
#undef sqrtl
#undef __strtold
long double ceill(long double ldArg);
long double expl(long double ldArg);
long double fabsl(long double ldArg);
long double floorl(long double ldArg);
long double fmodl(long double ldTop, long double ldBottom);
long double logl(long double ldArg);
long double log10l(long double ldArg);
long double log2l(long double ldArg);
long double powl(long double ldBase, long double ldExp);
long double sqrtl(long double ldArg);
#endif
#ifdef __i386__
char * szLDtoHex(char *sz, long double ld);
#endif
#if defined(__DJGPP__) && (__DJGPP <= 2) \
&& defined(__DJGPP_MINOR__) && (__DJGPP_MINOR__ <= 4)
#define strtold _strtold
#else
#define _atold(x) strtold(x, NULL)
#define _strtold strtold
#endif
#undef __nearbyintl
long double __nearbyintl(long double ld); /* custom implementation */
/**********************************************************************/
/********************* END LONG DOUBLE FUNCTIONS **********************/
/**********************************************************************/
/**********************************************************************/
/****************** CONIO EMULATIONS FOR NON-DOS **********************/
/**********************************************************************/
#ifndef __MSDOS__
/* At this time, only the screenheight and screenwidth fields return
meaningful values from gettextinfo. */
struct text_info {
unsigned char winleft; /* left window coordinate */
unsigned char wintop; /* top window coordinate */
unsigned char winright; /* right window coordinate */
unsigned char winbottom; /* bottom window coordinate */
unsigned char attribute; /* text attribute */
unsigned char normattr; /* text attribute at progr invoc */
unsigned char currmode; /* BW40, BW80, C40, C80, C4350 */
unsigned char screenheight; /* lines per screen */
unsigned char screenwidth; /* characters per line */
unsigned char curx; /* cursor x-coord in current window */
unsigned char cury; /* cursor y-coord in current window */
};
enum text_modes { LASTMODE=-1, BW40=0, C40, BW80, C80, MONO=7, C4350=64 };
enum COLORS {
/* dark colors */
BLACK,
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHTGRAY,
/* light colors */
DARKGRAY, /* charcoal */
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE
};
void clrscr(void);
int getch(void);
void gettextinfo(struct text_info *ti);
void gotoxy(int x, int y);
void highvideo(void);
void lowvideo(void);
void normvideo(void);
/**********************************************************************/
/**********************************************************************/
/* The functionality of the following CONIO routines is not presently
supported outside of DOS; the placeholders simply return (in the
case of kbhit, with a value of zero). */
int kbhit(void);
void textmode(int newmode);
void textattr(int newattr);
void textbackground(int newcolor);
void textcolor(int newcolor);
#endif /* conio emulations for non-DOS */
/**********************************************************************/
/************************** CONIO EXTENSIONS **************************/
/**********************************************************************/
/* The following function will clear the current line, leave the cursor
at the left margin, and set the global extern variables __iSW and
__iSH to the current screen width and screen height. */
void __clearline(void);
#undef __CLEAR_LINE__
#define __CLEAR_LINE__ __clearline()
void __nocursor(void);
void __normalcursor(void);
/**********************************************************************/
/**********************************************************************/
/* */
/* Define deprecrated identifiers to be equivalent to current ones. */
/* */
/* To activate this section, place the directive */
/* #define _OLD_IDENTIFIERS_TRN just before #include "trn.h". */
/* */
/**********************************************************************/
/**********************************************************************/
#ifdef _OLD_IDENTIFIERS_TRN
#undef _ceill
#undef _expl
#undef _fabsl
#undef _floorl
#undef _fmodl
#undef _logl
#undef _log10l
#undef _powl
#undef _sqrtl
#define _ceill ceill
#define _expl expl
#define _fabsl fabsl
#define _floorl floorl
#define _fmodl fmodl
#define _logl logl
#define _log10l log10l
#define _powl powl
#define _sqrtl sqrtl
#ifndef CLEAR_LINE
#define CLEAR_LINE __clearline()
#endif
#ifndef fzero
#define fzero _vZeroFile
#endif
#ifndef MAX_DIGITS
#define MAX_DIGITS __MAX_DIGITS__
#endif
#ifndef MAX_BITS
#define MAX_BITS __MAX_BITS__
#endif
#ifndef VSPACE
#define VSPACE __OBSL__
#endif
#ifndef __PRINT_BLANK_LINE__
#define __PRINT_BLANK_LINE__ __OBSL__
#endif
#endif /* _OLD_IDENTIFIERS_TRN */
#endif /* _TRN_H_ */