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

📄 makedesc.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
字号:
#include <stdio.h>#include <NTL/version.h>#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || defined(__i586__)))#define AutoFix (1)#else#define AutoFix (0)#endiflong f1(void);long f2(long bpl);double f3(void);void f4(double *p);void f5(int *p);long f6(void);long f7(void);long f8(void);double power2(long k){   long i;   double res;   res = 1;   for (i = 1; i <= k; i++)      res = res * 2;   return res;}long DoubleRounding(long dp){   double a = power2(dp-1) + 1;   double b = (power2(dp-6)-1)/power2(dp-5);   double x;   x = a + b;   f4(&x);   if (x != power2(dp-1) + 1)      return 1;   else       return 0; }long DoublePrecision(){   long k;   double l1 = (double)1;   double lh = 1/(double)2;   double epsilon;   double fudge, oldfudge;   epsilon = l1;   fudge = l1+l1;   k = 0;   do {      k++;      epsilon = epsilon * lh;      oldfudge = fudge;      fudge = l1 + epsilon;      f4(&fudge);      f4(&oldfudge);   } while (fudge > l1 && fudge < oldfudge);   return k;}long DoublePrecision1(){   register double fudge, oldfudge;   long k;   double l1 = (double)1;   double lh = 1/(double)2;   double epsilon;   epsilon = l1;   fudge = l1+l1;   k = 0;   do {      k++;      epsilon = epsilon * lh;      oldfudge = fudge;      fudge = l1 + epsilon;   } while (fudge > l1 && fudge < oldfudge);   return k;}union d_or_rep {   double d;   unsigned long rep[2];};long RepTest(void){   union d_or_rep v;   v.rep[0] = v.rep[1] = 0;   v.d = 565656565656.0;   if (v.rep[0] == 0x42607678 && v.rep[1] == 0x46f30000)      return 1;   else if (v.rep[1] == 0x42607678 && v.rep[0] == 0x46f30000)      return -1;   else      return 0;}void print2k(FILE *f, long k, long bpl){   long m, l;   long first;   if (k <= 0) {      fprintf(f, "((double) 1.0)");      return;   }   m = bpl - 2;   first = 1;   fprintf(f, "(");   while (k > 0) {      if (k > m)         l = m;      else         l = k;      k = k - l;      if (first)         first = 0;      else          fprintf(f, "*");      fprintf(f, "((double)(1L<<%ld))", l);   }   fprintf(f, ")");}void print_BB_mul_code(FILE *f, long n){   long i;   fprintf(f, "\n\n");   fprintf(f, "#define NTL_BB_MUL_CODE \\\n");   for (i = n-6; i >= 2; i -= 2) {      fprintf(f, "hi=(hi<<2)|(lo>>%ld); ", n-2);      fprintf(f, "lo=(lo<<2)^A[(b>>%ld)&3];\\\n", i);    }   fprintf(f, "\n\n");}void print_BB_half_mul_code(FILE *f, long n){   long i;   fprintf(f, "\n\n");   fprintf(f, "#define NTL_BB_HALF_MUL_CODE \\\n");   for (i = n/2-6; i >= 2; i -= 2) {      fprintf(f, "hi=(hi<<2)|(lo>>%ld); ", n-2);      fprintf(f, "lo=(lo<<2)^A[(b>>%ld)&3];\\\n", i);    }   fprintf(f, "\n\n");}void print_BB_sqr_code(FILE *f, long n){   long i, pos;   fprintf(f, "\n\n");   fprintf(f, "#define NTL_BB_SQR_CODE \\\n");   fprintf(f, "lo=sqrtab[a&255];\\\n");   pos = 16;   for (i = 8; i < n; i += 8) {      if (2*(i+8) <= n) {         fprintf(f, "lo=lo|(sqrtab[(a>>%ld)&255]<<%ld);\\\n", i, pos);         pos += 16;      }      else if (2*i == n) {         fprintf(f, "hi=sqrtab[(a>>%ld)&255];\\\n", i);         pos = 16;      }      else if (2*i > n) {         fprintf(f, "hi=hi|(sqrtab[(a>>%ld)&255]<<%ld);\\\n", i, pos);         pos += 16;      }      else { /* only applies if word size is not a multiple of 16 */         fprintf(f, "_ntl_ulong t=sqrtab[(a>>%ld)&255];\\\n", i);         fprintf(f, "lo=lo|(t<<%ld);\\\n", pos);         fprintf(f, "hi=t>>%ld;\\\n", n-8);         pos = 8;      }   }   fprintf(f, "\n\n");}void print_BB_rev_code(FILE *f, long n){   long i;   fprintf(f, "\n\n");   fprintf(f, "#define NTL_BB_REV_CODE ");   for (i = 0; i < n; i += 8) {      if (i != 0) fprintf(f, "\\\n|");      fprintf(f, "(revtab[(a>>%ld)&255]<<%ld)", i, n-8-i);   }   fprintf(f, "\n\n");}   char *yn_vec[2] = { "no", "yes" }; int main(){   long bpl, bpi, rs_arith, nbits, single_mul_ok;   long a;   long x;   long dp, dp1, dr;   FILE *f;   int xx;   long warnings = 0;   int c;   fprintf(stderr, "This is NTL version %s\n\n", NTL_VERSION);   x = f1();   if (~x != f8()) {      fprintf(stderr, "BAD NEWS: machine must be 2's compliment.\n");      return 1;   }   if ((x >> 1) == x)      rs_arith = 1;   else      rs_arith = 0;   bpl = 0;   while (x != 0) {      x = x << 1;      bpl++;   }   bpi = 0;   xx = 1;   while (xx) {      xx = xx << 1;       bpi++;      f5(&xx);   }   a = f2(bpl);   if (2*a != f7() || a*a != f6()) {      fprintf(stderr, "BAD NEWS: machine must work modulo 2^wordsize.\n");      return 1;   }   if (((long)f3()) != 1.0) {      fprintf(stderr, "BAD NEWS: machine must truncate floating point.\n");      return 1;   }   if (bpl & 7) {      fprintf(stderr, "BAD NEWS: word size must be multiple of 8 bits.\n");      return 1;   }   if (bpl < 32) {      fprintf(stderr, "BAD NEWS: word size must be at least 32 bits.\n");      return 1;   }   dp = DoublePrecision();   dp1 = DoublePrecision1();   dr = DoubleRounding(dp);   if (bpl-2 < dp-3)      nbits = bpl-2;   else      nbits = dp-3;   if (nbits & 1) nbits--;   if (nbits < 30) {      fprintf(stderr, "BAD NEWS: NBITS too small.\n");      return 1;   }   single_mul_ok = RepTest();   fprintf(stderr, "GOOD NEWS: compatible machine.\n");   fprintf(stderr, "summary of machine characteristics:\n");   fprintf(stderr, "bits per long = %ld\n", bpl);   fprintf(stderr, "bits per int = %ld\n", bpi);   fprintf(stderr, "arith right shift = %s\n", yn_vec[rs_arith]);   fprintf(stderr, "double precision = %ld\n", dp);   fprintf(stderr, "NBITS (maximum) = %ld\n", nbits);   fprintf(stderr, "single mul ok = %s\n", yn_vec[single_mul_ok != 0]);   fprintf(stderr, "extended doubles = %s\n", yn_vec[dp1 > dp]);   fprintf(stderr, "double rounding = %s\n", yn_vec[dr]);   if (dp1 > dp && AutoFix)      fprintf(stderr, "-- auto x86 fix\n");   if (dp != 53) {      warnings = 1;      fprintf(stderr, "\n\nWARNING:\n\n");       fprintf(stderr, "Nonstandard floating point precision.\n");      fprintf(stderr, "IEEE standard is 53 bits.\n");    }#if (defined(__sparc__) && !defined(__sparc_v8__))   warnings = 1;   fprintf(stderr, "\n\nWARNING:\n\n");   fprintf(stderr, "If this Sparc is a Sparc-10 or later (so it has\n");   fprintf(stderr, "a hardware integer multiply instruction) you\n");   fprintf(stderr, "should specify the -mv8 option in the makefile\n");    fprintf(stderr, "to obtain more efficient code.\n");#endif   if (dp1 > dp && !AutoFix) {      warnings = 1;      fprintf(stderr, "\n\nWARNING:\n\n");      fprintf(stderr, "This platform has extended double precision registers.\n");      fprintf(stderr, "While that may sound like a good thing, it actually is not.\n");      fprintf(stderr, "If this is a Pentium or other x86 and your compiler\n");      fprintf(stderr, "is g++ or supports GNU 'asm' constructs, it is recommended\n");      fprintf(stderr, "to compile NTL with the NTL_X86_FIX flag to get true IEEE floating point.\n");      fprintf(stderr, "Set this flag by editing the file config.h.\n");      fprintf(stderr, "The code should still work even if you don't set\n");      fprintf(stderr, "this flag.  See quad_float.txt for details.\n\n");   }   if (dp1 <= dp && dr) {      warnings = 1;      fprintf(stderr, "\n\nWARNING:\n\n");      fprintf(stderr, "Hmm....your machine double rounds, but the measured precision\n");      fprintf(stderr, "does not reflect this.\n");      fprintf(stderr, "Make sure you have optimizations turned on.\n\n");   }#if 0   /* better not to be interactive */   if (warnings) {      fprintf(stderr, "Do you want to continue anyway[y/n]? ");      c = getchar();      if (c == 'n' || c == 'N') {         fprintf(stderr, "Make the necessary changes to the makefile and/or config.h,\n");         fprintf(stderr, "then type 'make clobber' and then 'make'.\n\n\n");         return 1;      }   }#endif   f = fopen("mach_desc.h", "w");   if (!f) {      fprintf(stderr, "can't open mach_desc.h for writing\n");      return 1;   }   fprintf(f, "#ifndef NTL_mach_desc__H\n");   fprintf(f, "#define NTL_mach_desc__H\n\n\n");   fprintf(f, "#define NTL_BITS_PER_LONG (%ld)\n", bpl);   fprintf(f, "#define NTL_MAX_LONG (%ldL)\n", ((long) ((1UL<<(bpl-1))-1UL)));   fprintf(f, "#define NTL_MAX_INT (%ld)\n", ((long) ((1UL<<(bpi-1))-1UL)));   fprintf(f, "#define NTL_BITS_PER_INT (%ld)\n", bpi);   fprintf(f, "#define NTL_ARITH_RIGHT_SHIFT (%ld)\n", rs_arith);   fprintf(f, "#define NTL_NBITS_MAX (%ld)\n", nbits);   fprintf(f, "#define NTL_DOUBLE_PRECISION (%ld)\n", dp);   fprintf(f, "#define NTL_FDOUBLE_PRECISION ");   print2k(f, dp-1, bpl);   fprintf(f, "\n");   fprintf(f, "#define NTL_QUAD_FLOAT_SPLIT (");   print2k(f, dp - (dp/2), bpl);   fprintf(f, "+1.0)\n");   fprintf(f, "#define NTL_EXT_DOUBLE (%d)\n", dp1 > dp);   fprintf(f, "#define NTL_SINGLE_MUL_OK (%d)\n", single_mul_ok != 0);   fprintf(f, "#define NTL_DOUBLES_LOW_HIGH (%d)\n\n\n", single_mul_ok < 0);   print_BB_mul_code(f, bpl);   print_BB_half_mul_code(f, bpl);   print_BB_sqr_code(f, bpl);   print_BB_rev_code(f, bpl);   fprintf(f, "#define NTL_MIN_LONG (-NTL_MAX_LONG - 1L)\n");   fprintf(f, "#define NTL_MIN_INT  (-NTL_MAX_INT - 1)\n");   fprintf(f, "#endif\n\n");   fclose(f);   fprintf(stderr, "\n\n");      return 0;}

⌨️ 快捷键说明

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