Beispiel #1
0
xdouble PowerOf10(const ZZ& e)
{
   static NTL_CHEAP_THREAD_LOCAL long init = 0;
   static NTL_CHEAP_THREAD_LOCAL long k = 0;

   NTL_TLS_LOCAL(xdouble, v10k);

   if (!init) {
      k = ComputeMax10Power();
      RRPush push;
      RR::SetPrecision(NTL_DOUBLE_PRECISION);
      v10k = to_xdouble(power(to_RR(10), k)); 
      init = 1;
   }

   ZZ e1;
   long neg;

   if (e < 0) {
      e1 = -e;
      neg = 1;
   }
   else {
      e1 = e;
      neg = 0;
   }

   long r;
   ZZ q;

   r = DivRem(q, e1, k);

   RRPush push;
   RR::SetPrecision(NTL_DOUBLE_PRECISION);
   xdouble x1 = to_xdouble(power(to_RR(10), r));

   xdouble x2 = power(v10k, q);
   xdouble x3 = x1*x2;

   if (neg) x3 = 1/x3;

   return x3;
}
Beispiel #2
0
long ComputeMax10Power()
{
   RRPush push;
   RR::SetPrecision(NTL_BITS_PER_LONG);

   RR ln2, ln10;
   ComputeLn2(ln2);
   ComputeLn10(ln10);

   long k = to_long( to_RR(NTL_OVFBND/2) * ln2 / ln10 );
   return k;
}
Beispiel #3
0
void ReallyComputePi(RR& res)
{
   long p = RR::precision();
   RR::SetPrecision(p + NumBits(p) + 10);


   RR sum1;

   RR s, s1, t, t1;

   s = 0;
   t = 0.5;
   t1 = 0.5;

   long i;

   for (i = 3; ; i+=2) {
      add(s1, s, t);
      if (s == s1) break;
      xcopy(s, s1);
      mul(t1, t1, -0.25);
      div(t, t1, i);
   }

   xcopy(sum1, s);


   RR g;

   inv(g, to_RR(3)); // g = 1/3

   s = 0;
   xcopy(t, g);
   xcopy(t1, g);

   sqr(g, g);
   negate(g, g); // g = -1/9

   for (i = 3; ; i+=2) {
      add(s1, s, t);
      if (s == s1) break;
      xcopy(s, s1);
      mul(t1, t1, g);
      div(t, t1, i);
   }

   add(s, s, sum1);
   mul(s, s, 4);

   RR::SetPrecision(p);
   xcopy(res, s);
}
Beispiel #4
0
void ComputeLn10(RR& res)
{
   static long prec = 0;
   static RR ln10;

   long p = RR::precision();

   if (prec <= p + 10) {
      prec = p + 20;
      RR::SetPrecision(prec);
      log(ln10, to_RR(10));
      RR::SetPrecision(p);
   }

   xcopy(res, ln10);
}
Beispiel #5
0
// ECM primitive
void ECM(ZZ& q, const ZZ& n, const ZZ& _bnd, double failure_prob,
	 bool verbose) {
  ZZ bnd;
  SqrRoot(bnd,n);
  if (_bnd>0 && _bnd<bnd)
    bnd=_bnd;

  long B1,B2,D;
  double prob;
  ECM_parameters(B1,B2,prob,D,NumBits(bnd),NumBits(n));
  if (verbose)
    std::cout<<"ECM: bnd="<<NumBits(bnd)<<"bits  B1="<<B1<<"  B2="<<B2
             <<"  D="<<D<<"  prob="<<prob<<std::endl;
  
  if (failure_prob<=0) {
    // run "forever"
    if (verbose)
      std::cout<<"ECM: expected ncurves="<<(1/prob)<<std::endl;
    ECM(q,n,NTL_MAX_LONG,B1,B2,D,verbose); 
  }
  else if (failure_prob>=1) {
    // run on one curve
    ECM(q,n,1,B1,B2,D,verbose); 
  }
  else {
    // run just the right number of times
    // failure_prob = (1-prob)^ncurves;
    double ncurves_d;
    if (prob<0.1)
      ncurves_d = to_double(log(failure_prob)/log1p(to_RR(-prob)));
    else
      ncurves_d = log(failure_prob)/log(1-prob);
    long ncurves = ncurves_d<=1 ? 1 :
      (ncurves_d>=NTL_MAX_LONG ? NTL_MAX_LONG : (long)ncurves_d);
    if (verbose)
      std::cout<<"ECM: good_prob="<<prob<<"  failure_prob="<<failure_prob
               <<"  ncurves="<<ncurves<<std::endl;
    ECM(q,n,ncurves,B1,B2,D,verbose); 
  }
}
Beispiel #6
0
ostream& operator<<(ostream& s, const xdouble& a)
{
   if (a == 0) {
      s << "0";
      return s;
   }

   RRPush push;
   long temp_p = long(log(fabs(log(fabs(a))) + 1.0)/log(2.0)) + 10; 
   RR::SetPrecision(temp_p);

   RR ln2, ln10, log_2_10;
   ComputeLn2(ln2);
   ComputeLn10(ln10);
   log_2_10 = ln10/ln2;
   ZZ log_10_a = to_ZZ(
  (to_RR(a.e)*to_RR(2*NTL_XD_HBOUND_LOG) + log(fabs(a.x))/log(2.0))/log_2_10);


   xdouble b;
   long neg;

   if (a < 0) {
      b = -a;
      neg = 1;
   }
   else {
      b = a;
      neg = 0;
   }

   ZZ k = xdouble::OutputPrecision() - log_10_a;

   xdouble c, d;

   c = PowerOf10(to_ZZ(xdouble::OutputPrecision()));
   d = PowerOf10(log_10_a);

   b = b / d;
   b = b * c;

   while (b < c) {
      b = b * 10.0;
      k++;
   }

   while (b >= c) {
      b = b / 10.0;
      k--;
   }

   b = b + 0.5;
   k = -k;

   ZZ B;
   conv(B, b);

   long bp_len = xdouble::OutputPrecision()+10;

   UniqueArray<char> bp_store;
   bp_store.SetLength(bp_len);
   char *bp = bp_store.get();

   long len, i;

   len = 0;
   do {
      if (len >= bp_len) LogicError("xdouble output: buffer overflow");
      bp[len] = IntValToChar(DivRem(B, B, 10));
      len++;
   } while (B > 0);

   for (i = 0; i < len/2; i++) {
      char tmp;
      tmp = bp[i];
      bp[i] = bp[len-1-i];
      bp[len-1-i] = tmp;
   }

   i = len-1;
   while (bp[i] == '0') i--;

   k += (len-1-i);
   len = i+1;

   bp[len] = '\0';

   if (k > 3 || k < -len - 3) {
      // use scientific notation

      if (neg) s << "-";
      s << "0." << bp << "e" << (k + len);
   }
   else {
      long kk = to_long(k);

      if (kk >= 0) {
         if (neg) s << "-";
         s << bp;
         for (i = 0; i < kk; i++) 
            s << "0";
      }
      else if (kk <= -len) {
         if (neg) s << "-";
         s << "0.";
         for (i = 0; i < -len-kk; i++)
            s << "0";
         s << bp;
      }
      else {
         if (neg) s << "-";
         for (i = 0; i < len+kk; i++)
            s << bp[i];
   
         s << ".";
   
         for (i = len+kk; i < len; i++)
            s << bp[i];
      }
   }

   return s;
}
Beispiel #7
0
void inv(RR& z, const RR& a)
{
   NTL_TLS_LOCAL_INIT(RR, one, (to_RR(1)));
   div(z, one, a);
}
Beispiel #8
0
void conv(RR& x, const char *s)
{
   long c;
   long cval;
   long sign;
   ZZ a, b;
   long i = 0;

   if (!s) Error("bad RR input");


   c = s[i];
   while (IsWhiteSpace(c)) {
      i++;
      c = s[i];
   }

   if (c == '-') {
      sign = -1;
      i++;
      c = s[i];
   }
   else
      sign = 1;

   long got1 = 0;
   long got_dot = 0;
   long got2 = 0;

   a = 0;
   b = 1;

   cval = CharToIntVal(c);

   if (cval >= 0 && cval <= 9) {
      got1 = 1;

      while (cval >= 0 && cval <= 9) {
         mul(a, a, 10);
         add(a, a, cval);
         i++;
         c = s[i];
         cval = CharToIntVal(c);
      }
   }

   if (c == '.') {
      got_dot = 1;

      i++;
      c = s[i];
      cval = CharToIntVal(c);

      if (cval >= 0 && cval <= 9) {
         got2 = 1;

         while (cval >= 0 && cval <= 9) {
            mul(a, a, 10);
            add(a, a, cval);
            mul(b, b, 10);
            i++;
            c = s[i];
            cval = CharToIntVal(c);
         }
      }
   }

   if (got_dot && !got1 && !got2)  Error("bad RR input");

   ZZ e;

   long got_e = 0;
   long e_sign;

   if (c == 'e' || c == 'E') {
      got_e = 1;

      i++;
      c = s[i];

      if (c == '-') {
         e_sign = -1;
         i++;
         c = s[i];
      }
      else if (c == '+') {
         e_sign = 1;
         i++;
         c = s[i];
      }
      else
         e_sign = 1;


      cval = CharToIntVal(c);

      if (cval < 0 || cval > 9) Error("bad RR input");

      e = 0;
      while (cval >= 0 && cval <= 9) {
         mul(e, e, 10);
         add(e, e, cval);
         i++;
         c = s[i];
         cval = CharToIntVal(c);
      }
   }

   if (!got1 && !got2 && !got_e) Error("bad RR input");

   RR t1, t2, v;

   long old_p = RR::precision();

   if (got1 || got2) {
      ConvPrec(t1, a, max(NumBits(a), 1));
      ConvPrec(t2, b, NumBits(b));
      if (got_e)
         RR::SetPrecision(old_p + 10);

      div(v, t1, t2);
   }
   else
      set(v);

   if (sign < 0)
      negate(v, v);

   if (got_e) {
      if (e >= NTL_OVFBND) Error("RR input overflow");
      long E;
      conv(E, e);
      if (e_sign < 0) E = -E;
      RR::SetPrecision(old_p + 10);
      power(t1, to_RR(10), E);
      mul(v, v, t1);
      RR::prec = old_p;
   }

   xcopy(x, v);
}
Beispiel #9
0
void inv(RR& z, const RR& a)
{
   static RR one = to_RR(1);
   div(z, one, a);
}