Ejemplo n.º 1
0
static cl_object
complex_divide(cl_object ar, cl_object ai, cl_object br, cl_object bi)
{
        /* #C(z1 z2) = #C(xr xi) * #C(yr -yi) */
        cl_object z1 = ecl_plus(ecl_times(ar, br), ecl_times(ai, bi));
        cl_object z2 = ecl_minus(ecl_times(ai, br), ecl_times(ar, bi));
        cl_object absB = ecl_plus(ecl_times(br, br), ecl_times(bi, bi));
        return ecl_make_complex(ecl_divide(z1, absB), ecl_divide(z2, absB));
}
Ejemplo n.º 2
0
static cl_object
prepare_ratio_to_float(cl_object num, cl_object den, int digits, cl_fixnum *scaleout)
{
        /* We have to cook our own routine because GMP does not round.
         * The recipe is simple: we multiply the numberator by a large
         * enough number so that the division by the denominator fits
         * the floating point number. The result is scaled back by the
         * appropriate exponent.
         */
        /* Scale down the denominator, eliminating the zeros
         * so that we have smaller operands.
         */
        cl_fixnum scale = remove_zeros(&den);
        cl_fixnum num_size = ecl_integer_length(num);
        cl_fixnum delta = ecl_integer_length(den) - num_size;
        scale -= delta;
        {
                cl_fixnum adjust = digits + delta + 1;
                if (adjust > 0) {
                        num = ecl_ash(num, adjust);
                } else if (adjust < 0) {
                        den = ecl_ash(den, -adjust);
                }
        }
        do {
		const cl_env_ptr the_env = ecl_process_env();
                cl_object fraction = ecl_truncate2(num, den);
                cl_object rem = ecl_nth_value(the_env, 1);
                cl_fixnum len = ecl_integer_length(fraction);
                if ((len - digits) == 1) {
                        if (ecl_oddp(fraction)) {
                                cl_object one = ecl_minusp(num)?
                                        ecl_make_fixnum(-1) :
                                        ecl_make_fixnum(1);
                                if (rem == ecl_make_fixnum(0)) {
                                        if (cl_logbitp(ecl_make_fixnum(1), fraction)
                                            != ECL_NIL)
                                                fraction = ecl_plus(fraction, one);
                                } else {
                                        fraction = ecl_plus(fraction, one);
                                }
                        }
                        *scaleout = scale - (digits + 1);
                        return fraction;
                }
                den = ecl_ash(den, 1);
                scale++;
        } while (1);
}
Ejemplo n.º 3
0
static cl_fixnum
scale(float_approx *approx)
{
        cl_fixnum k = 0;
        cl_object x = ecl_plus(approx->r, approx->mp);
        int sign;
        do {
                sign = ecl_number_compare(x, approx->s);
                if (approx->high_ok) {
                        if (sign < 0)
                                break;
                } else {
                        if (sign <= 0)
                                break;
                }
                approx->s = ecl_times(approx->s, PRINT_BASE);
                k++;
        } while(1);
        do {
                x = ecl_times(x, PRINT_BASE);
                sign = ecl_number_compare(x, approx->s);
                if (approx->high_ok) {
                        if (sign >= 0)
                                break;
                } else {
                        if (sign > 0)
                                break;
                }
                k--;
                approx->r = ecl_times(approx->r, PRINT_BASE);
                approx->mm = ecl_times(approx->mm, PRINT_BASE);
                approx->mp = ecl_times(approx->mp, PRINT_BASE);
        } while(1);
        return k;
}
Ejemplo n.º 4
0
static cl_object
generate(cl_object digits, float_approx *approx)
{
        cl_object d, x;
        cl_fixnum digit;
        bool tc1, tc2;
        do {
                d = ecl_truncate2(ecl_times(approx->r, PRINT_BASE), approx->s);
                approx->r = VALUES(1);
                approx->mp = ecl_times(approx->mp, PRINT_BASE);
                approx->mm = ecl_times(approx->mm, PRINT_BASE);
                tc1 = approx->low_ok?
                        ecl_lowereq(approx->r, approx->mm) :
                        ecl_lower(approx->r, approx->mm);
                x = ecl_plus(approx->r, approx->mp);
                tc2 = approx->high_ok?
                        ecl_greatereq(x, approx->s) :
                        ecl_greater(x, approx->s);
                if (tc1 || tc2) {
                        break;
                }
                ecl_string_push_extend(digits, ecl_digit_char(ecl_fixnum(d), 10));
        } while (1);
        if (tc2 && !tc1) {
                digit = ecl_fixnum(d) + 1;
        } else if (tc1 && !tc2) {
                digit = ecl_fixnum(d);
        } else if (ecl_lower(times2(approx->r), approx->s)) {
                digit = ecl_fixnum(d);
        } else {
                digit = ecl_fixnum(d) + 1;
        }
        ecl_string_push_extend(digits, ecl_digit_char(digit, 10));
        return digits;
}
Ejemplo n.º 5
0
static void
change_precision(float_approx *approx, cl_object position, cl_object relativep)
{
        cl_fixnum pos;
        if (Null(position))
                return;
        pos = ecl_fixnum(position);
        if (!Null(relativep)) {
                cl_object k = ecl_make_fixnum(0);
                cl_object l = ecl_make_fixnum(1);
                while (ecl_lower(ecl_times(approx->s, l),
                                 ecl_plus(approx->r, approx->mp))) {
                        k = ecl_one_plus(k);
                        l = ecl_times(l, PRINT_BASE);
                }
                position = ecl_minus(k, position);
                {
                        cl_object e1 = cl_expt(PRINT_BASE, position);
                        cl_object e2 = ecl_divide(e1, ecl_make_fixnum(2));
                        cl_object e3 = cl_expt(PRINT_BASE, k); 
                        if (ecl_greatereq(ecl_plus(approx->r, ecl_times(approx->s, e1)),
                                          ecl_times(approx->s, e2)))
                                position = ecl_one_minus(position);
                }
        }
        {
                cl_object x = ecl_times(approx->s, cl_expt(PRINT_BASE, position));
                cl_object e = ecl_divide(x, ecl_make_fixnum(2));
                cl_object low = cl_max(2, approx->mm, e);
                cl_object high = cl_max(2, approx->mp, e);
                if (ecl_lowereq(approx->mm, low)) {
                        approx->mm = low;
                        approx->low_ok = 1;
                }
                if (ecl_lowereq(approx->mp, high)) {
                        approx->mp = high;
                        approx->high_ok = 1;
                }
        }
}
Ejemplo n.º 6
0
cl_object
_ecl_long_double_to_integer(long double d0)
{
        const int fb = FIXNUM_BITS - 3;
        int e;
        long double d = frexpl(d0, &e);
        if (e <= fb) {
                return ecl_make_fixnum((cl_fixnum)d0);
        } else if (e > LDBL_MANT_DIG) {
                return ecl_ash(_ecl_long_double_to_integer(ldexp(d, LDBL_MANT_DIG)),
                               e - LDBL_MANT_DIG);
        } else {
                long double d1 = floorl(d = ldexpl(d, fb));
                int newe = e - fb;
                cl_object o = ecl_ash(_ecl_long_double_to_integer(d1), newe);
                long double d2 = ldexpl(d - d1, newe);
                if (d2) o = ecl_plus(o, _ecl_long_double_to_integer(d2));
                return o;
        }
}
Ejemplo n.º 7
0
static cl_object
times2(cl_object x)
{
        return ecl_plus(x, x);
}
Ejemplo n.º 8
0
/*	optimize speed 3, debug 3, space 0, safety 2                  */
static cl_object L1seq(cl_narg narg, ...)
{
 cl_object T0;
 struct ecl_ihs_frame ihs;
 const cl_object _ecl_debug_env = ECL_NIL;
 const cl_env_ptr cl_env_copy = ecl_process_env();
 cl_object value0;
 ecl_cs_check(cl_env_copy,value0);
 {
  cl_object V1;
  cl_object V2;
  cl_object V3;
  ecl_va_list args; ecl_va_start(args,narg,narg,0);
  {
   ecl_ihs_push(cl_env_copy,&ihs,VV[0],_ecl_debug_env);
   {
    cl_object keyvars[6];
    cl_parse_key(args,3,L1seqkeys,keyvars,NULL,FALSE);
    ecl_va_end(args);
    if (Null(keyvars[3])) {
     V1 = ecl_make_fixnum(0);
    } else {
     V1 = keyvars[0];
    }
    if (Null(keyvars[4])) {
     V2 = ecl_make_fixnum(10);
    } else {
     V2 = keyvars[1];
    }
    if (Null(keyvars[5])) {
     V3 = ecl_make_fixnum(1);
    } else {
     V3 = keyvars[2];
    }
   }
   {
    cl_object V4;                                 /*  I               */
    cl_object V5;
    cl_object V6;
    {
     T0 = cl_realp(V1);
     if (ecl_unlikely(!((T0)!=ECL_NIL)))
         FEwrong_type_argument(ECL_SYM("REAL",703),V1);
     V4 = V1;
    }
    {
     T0 = cl_realp(V2);
     if (ecl_unlikely(!((T0)!=ECL_NIL)))
         FEwrong_type_argument(ECL_SYM("REAL",703),V2);
     V5 = V2;
    }
    {
     T0 = cl_realp(V3);
     if (ecl_unlikely(!((T0)!=ECL_NIL)))
         FEwrong_type_argument(ECL_SYM("REAL",703),V3);
     V6 = V3;
    }
    {
     static const struct ecl_var_debug_info _ecl_descriptors[]={
     {"#:LOOP-STEP-BY1",_ecl_object_loc}
     ,{"#:LOOP-LIMIT0",_ecl_object_loc}
     ,{"COMMON-LISP-USER::I",_ecl_object_loc}};
     const cl_index _ecl_debug_info_raw[]={
     (cl_index)(_ecl_debug_env),(cl_index)(_ecl_descriptors),(cl_index)(&V6),(cl_index)(&V5),(cl_index)(&V4)};
     ecl_def_ct_vector(_ecl_debug_env,ecl_aet_index,_ecl_debug_info_raw,5,,);
     ihs.lex_env = _ecl_debug_env;
     {
      cl_object V7;
      cl_object V8;
      V7 = ecl_list1(ECL_NIL);
      V8 = V7;
      {
       static const struct ecl_var_debug_info _ecl_descriptors[]={
       {"#:LOOP-LIST-TAIL3",_ecl_object_loc}
       ,{"#:LOOP-LIST-HEAD2",_ecl_object_loc}};
       const cl_index _ecl_debug_info_raw[]={
       (cl_index)(_ecl_debug_env),(cl_index)(_ecl_descriptors),(cl_index)(&V8),(cl_index)(&V7)};
       ecl_def_ct_vector(_ecl_debug_env,ecl_aet_index,_ecl_debug_info_raw,4,,);
       ihs.lex_env = _ecl_debug_env;
L12:;
       if (!(ecl_number_compare(V4,V5)>0)) { goto L14; }
       goto L13;
L14:;
       T0 = V8;
       V8 = ecl_list1(V4);
       cl_rplacd(T0, V8);
       V4 = ecl_plus(V4,V6);
       goto L12;
L13:;
       value0 = ecl_cdr(V7);
       cl_env_copy->nvalues = 1;
       ecl_ihs_pop(cl_env_copy);
       return value0;
      }
      ihs.lex_env = _ecl_debug_env;
     }
    }
    ihs.lex_env = _ecl_debug_env;
   }
  }
 }
}