/* CRT.H */ /* ** This file is placed into the public domain by its author, ** Carey Bloodworth (Carey@Bloodworth.org) on July 16, 2001 ** ** This file is part of mpntt31.c, a simple multi-prime NTT */ /* ** For portability reasons, I'm using 16 bit short integers. ** Obviously, for performance, you'd use a full word and some assembly. ** This means the CRT_LEN is twice the number of primes. Assuming, of ** course, that ModInt is a 32 bit int. */ #define CRT_LEN (NPrimes*2) typedef unsigned short int CRTNum; void ClearCRT(CRTNum *Num) {int x; for (x=0;xLimit[x]) {break;} B=0; for (x=CRT_LEN-1;x>=0;x--) { D=((UINT32)Num[x])-((UINT32)Limit[x])-B; B=0; if (D < 0) {D+=0x10000;B=1;} Num[x]=D; } } void MulCRT(CRTNum *Num, ModInt Val,int Len) /* Multiply the CRT by a ModInt */ {double P,T; P=0; while (Len--) { P=((double)Num[Len])*Val+P; T=floor(P/65536.0); Num[Len]=P-T*65536.0; P=T; } } static void Add2CRT(CRTNum *Num1, CRTNum *Num2) {UINT32 S,C; int x; C=0; for (x=CRT_LEN-1;x>=0;x--) { S=((UINT32)Num1[x])+((UINT32)Num2[x])+C; C=0; if (S >= 65536) {S-= 65536;C=1;} Num1[x]=S; } } UINT32 StripCRT(CRTNum *Num) {double D1;int x; double DBase=BASE; /* global constant needed as a double */ D1=0.0; for (x=0;x