📄 bignum.h
字号:
#include <math.h>
#ifndef RADIX_BITS /* If not previously #included */
#define MP_LONGEST_BITS 2048
/*
Multiple precision moduli can have up to
MP_LONGEST_BITS bits, which is
MP_LONGEST words. Some routines allow
longer operands.
*/
/*
Error messages are not printed in the
production version of the code.
In the test version, compiled
by MSCV with ENABLE_ERROR_MESSAGES
listed under PREPROCESSOR DEFINITIONS
in the project workspace, they are printed,
*/
#ifndef PRINT_ERROR_MESSAGES
#ifdef ENABLE_ERROR_MESSAGES
#define PRINT_ERROR_MESSAGES 1
#else
#define PRINT_ERROR_MESSAGES 0
#endif
#endif
#if PRINT_ERROR_MESSAGES
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#endif
#define COMPILER_GCC 1
#define COMPILER_VC 2
#ifndef COMPILER
#ifdef __GNUC__
#define COMPILER COMPILER_GCC
/* GNU compiler */
#endif
#ifdef _MSC_VER
#define COMPILER COMPILER_VC
#endif /* Microsoft Visual C compiler */
#endif
#if !defined(COMPILER) || COMPILER <= 0
#error -- "Unknown COMPILER"
#endif
#define COMPILER_NAME ( \
COMPILER == COMPILER_GCC ? "GCC compiler" \
: COMPILER == COMPILER_VC ? "Microsoft Visual C++ compiler" \
: "Unknown compiler")
/*
List of architectures on which code has been run.
The SPARC code was used only during development,
and is not a deliverable.
*/
#define TARGET_ALPHA 1
#define TARGET_IX86 2
#define TARGET_MIPS 3
#define TARGET_PPC 4
#define TARGET_SPARC 5
#define TARGET_IA64 6
#ifndef TARGET
#ifdef _M_ALPHA
#define TARGET TARGET_ALPHA
#endif
#ifdef _M_IX86
#define TARGET TARGET_IX86
#endif
#ifdef _M_MRX000
#define TARGET TARGET_MIPS
#endif
#ifdef _M_PPC
#define TARGET TARGET_PPC
#endif
#ifdef __sparc__
#define TARGET TARGET_SPARC
#endif
#ifdef _M_IA64
#define TARGET TARGET_IA64
#endif
#endif
#if !defined(TARGET) || TARGET <= 0
#error -- "Unknown TARGET"
#endif
#define TARGET_NAME ( \
TARGET == TARGET_ALPHA ? "DEC Alpha" \
: TARGET == TARGET_IX86 ? "Intel x86 (x >= 3) and Pentium" \
: TARGET == TARGET_MIPS ? "MIPS R2000/R3000" \
: TARGET == TARGET_PPC ? "Macintosh PowerPC" \
: TARGET == TARGET_SPARC ? "Sun SPARC" \
: TARGET == TARGET_IA64 ? "Intel IA64" \
: "Unknown target architecture")
/*
USEASM_ALPHA, ... specify whether to use assembly language,
if it has been written for a platform.
*/
#ifndef USEASM
#if TARGET == TARGET_IX86
#define USEASM 1
#elif TARGET == TARGET_ALPHA
#define USEASM 1
#else
#define USEASM 0
#endif
#endif
#define USEASM_ALPHA (USEASM && TARGET == TARGET_ALPHA)
#define USEASM_IX86 (USEASM && TARGET == TARGET_IX86)
#define USEASM_MIPS (USEASM && TARGET == TARGET_MIPS)
#define USEASM_PPC (USEASM && TARGET == TARGET_PPC)
#define USEASM_SPARC (USEASM && TARGET == TARGET_SPARC)
#define USEASM_IA64 (USEASM && TARGET == TARGET_IA64)
#if COMPILER == COMPILER_VC
/*
Visual C recognizes _inline but not inline.
*/
#define inline _inline
#pragma intrinsic(abs, labs, memcpy, memset)
#pragma warning(disable: 4146 4514)
/* 4146 -- unary minus operator applied
to unsigned type, result still unsigned.
4514 -- unreferenced inline function
*/
#endif
/*
x86 assembly routines are declared naked,
so they do their own stack management and
register saving.
When using a DLL on Intel platforms, all functions use
the __stdcall convention, so the assembly routines use it too.
To ensure they are called with the __stdcall
conventions always (i.e., even when compiled under Microsoft
Developer Studio), we put __stdcall explicitly in the prototypes.
*/
#if USEASM_IX86
#define Naked86 __declspec(naked)
#define Stdcall86 __stdcall
#else
#define Naked86
#define Stdcall86
#endif
#if (TARGET == TARGET_ALPHA) || (TARGET == TARGET_IA64)
#define RADIX_BITS 64
#define RADIX_BYTES 8
typedef unsigned __int64 digit_t;
#else
#define RADIX_BITS 32
#define RADIX_BYTES 4
typedef unsigned __int32 digit_t;
#endif
#define MP_LONGEST (MP_LONGEST_BITS/RADIX_BITS)
#if MP_LONGEST_BITS == RADIX_BITS
#define LG2_MP_LONGEST 0
#elif MP_LONGEST_BITS == 2*RADIX_BITS
#define LG2_MP_LONGEST 1
#elif MP_LONGEST_BITS == 4*RADIX_BITS
#define LG2_MP_LONGEST 2
#elif MP_LONGEST_BITS == 8*RADIX_BITS
#define LG2_MP_LONGEST 3
#elif MP_LONGEST_BITS == 16*RADIX_BITS
#define LG2_MP_LONGEST 4
#elif MP_LONGEST_BITS == 32*RADIX_BITS
#define LG2_MP_LONGEST 5
#elif MP_LONGEST_BITS == 64*RADIX_BITS
#define LG2_MP_LONGEST 6
#elif MP_LONGEST_BITS == 128*RADIX_BITS
#define LG2_MP_LONGEST 7
#elif MP_LONGEST_BITS == 256*RADIX_BITS
#define LG2_MP_LONGEST 8
#else
#define LG2_MP_LONGEST 0
#endif
#if MP_LONGEST_BITS != RADIX_BITS << LG2_MP_LONGEST
#error "Unrecognized value of MP_LONGEST_BITS"
#endif
/*
The letter 'c' following a type name identifies
a const entity of that type.
*/
typedef const char charc;
typedef const digit_t digit_tc;
typedef const int intc;
typedef int BOOL; /* Same as windef.h */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define DIGIT_ZERO ((digit_t)0)
#define DIGIT_ONE ((digit_t)1)
#define RADIX_HALF (DIGIT_ONE << (RADIX_BITS - 1))
#define RADIXM1 (-DIGIT_ONE)
#define F_RADIX ((double)RADIXM1 + 1.0)
#define HALF_RADIX_BITS (RADIX_BITS/2)
#if (RADIX_BITS != 2*HALF_RADIX_BITS)
#error -- "RADIX_BITS must be even"
#endif
#define RADIX_HALFMASK_BOTTOM (RADIXM1 >> HALF_RADIX_BITS)
#include "dblint.h"
// Multiple-precision data is normally represented
// in radix 2^RADIX_BITS, with RADIX_BITS bits per word.
// Here ``word'' means type digit_t. RADIX_BITS
// is 32 on some architectures (Intel, MIPS, PowerPC)
// and 64 bits on other architectures (Alpha).
// Within Windows NT, the data type DWORD predominates.
// DWORD is a 32-bit unsigned datatype on all platforms
// (Intel, Alpha, MIPS, PowerPC). DWORD data can safely be
// written to disk on one architecture and read back on another,
// unlike digit_t.
typedef unsigned char BYTE;
typedef unsigned long DWORD;
typedef const DWORD DWORDC;
#define DWORD_BITS 32
#define DWORD_LEFT_BIT 0x80000000UL
#if RADIX_BITS % DWORD_BITS != 0
#error "RADIX_BITS not a multiple of 32"
#endif
#define DWORDS_PER_DIGIT (RADIX_BITS/DWORD_BITS)
// DWORDS_TO_DIGITS(lng_dwords) computes the number of digit_t
// elements required to store an array with -lng_dwords- DWORDs.
// DIGITS_TO_DWORDS converts in the opposite direction.
#define DWORDS_TO_DIGITS(lng_dwords) \
( ((lng_dwords) + DWORDS_PER_DIGIT - 1)/DWORDS_PER_DIGIT)
#define DIGITS_TO_DWORDS(lng_digits) ((lng_digits) * DWORDS_PER_DIGIT)
/*
DOUBLE_SHIFT_LEFT(n1, n0, amt) returns
n1 shifted left by amt bits,
with new bits coming in from the top of n0.
DOUBLE_SHIFT_RIGHT(n1, n0, amt) returns n0 shifted right
by amt bits, with new bits coming from the bottom of n1.
The shift counts must satisfy 0 <= amt <= RADIX_BITS - 1.
The shift by RADIX_BITS - amt is done in two stages
(first by 1, then by RADIX_BITS - 1 - amt),
to avoid an illegal shift count of RADIX_BITS if amt = 0.
*/
#define DOUBLE_SHIFT_LEFT(n1, n0, amt) \
(((n1) << (amt)) | (((n0) >> 1) >> (RADIX_BITS - 1 - (amt))))
#define DOUBLE_SHIFT_RIGHT(n1, n0, amt) \
(((n0) >> (amt)) | (((n1) << 1) << (RADIX_BITS - 1 - (amt))))
#define digit_getbit(iword, ibit) (((iword) >> (ibit)) & 1)
#define dword_getbit(iword, ibit) digit_getbit(iword, ibit)
/* Extract bit from a word.
// 0 <= ibit <= RADIX_BITS - 1.
// Rightmost (i.e., least significant) bit is bit 0.
*/
/*
Test whether a number is odd or even.
*/
#define IS_EVEN(n) (~(n) & 1)
#define IS_ODD(n) ((n) & 1)
/*
Maximum and minimum of two arguments
(no side effects in arguments)
*/
#if 0
#define MAX _max
#define MIN _min
#else
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define MIN(x, y) ((x) > (y) ? (y) : (x))
#endif
#if 0
/*
If we are building a DLL, use __declspec before certain variable
declarations (and out procedure names in a .def file).
_PM_DLL should be #defined when compiling bignum but not the application.
If we are building a static library, use normal C declarations.
*/
#ifdef _PM_DLL
#define exportable_var __declspec( dllexport )
#define exportable_var_declaration __declspec (dllexport)
#else
#define exportable_var __declspec( dllimport )
#endif
#else
#define exportable_var extern
#define exportable_var_declaration
#endif
#
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -