Created _ecl_fix_times_fix and used it in num_arith.d
authorJuan Jose Garcia Ripoll <jjgarcia@jjgr-2.local>
Thu, 28 Jan 2010 21:13:40 +0000 (22:13 +0100)
committerJuan Jose Garcia Ripoll <jjgarcia@jjgr-2.local>
Thu, 28 Jan 2010 21:13:40 +0000 (22:13 +0100)
src/c/big.d
src/c/big_ll.d
src/c/num_arith.d
src/h/external.h

index 7a1c917..89198ec 100644 (file)
@@ -146,6 +146,35 @@ static const limbs_per_fixnum = 1;
 static conts limbs_per_fixnum = (FIXNUM_BITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
 #endif
 
+#define WITH_TEMP_BIGNUM(name,n)                                        \
+        mp_limb_t name##data[n];                                        \
+        volatile struct ecl_bignum name##aux;                           \
+        const cl_object name = (name##aux.big_num->_mp_alloc = n,       \
+                                name##aux.big_num->_mp_size = 0,        \
+                                name##aux.big_num->_mp_d = name##data,  \
+                                (cl_object)(&name##aux))
+
+cl_object
+_ecl_fix_times_fix(cl_fixnum x, cl_fixnum y)
+{
+#if ECL_LONG_BITS >= FIXNUM_BITS
+        WITH_TEMP_BIGNUM(z,4);
+        mpz_set_si(z->big.big_num, x);
+        mpz_mul_si(z->big.big_num, z->big.big_num, y);
+#else
+        WITH_TEMP_BIGNUM(z,4);
+        WITH_TEMP_BIGNUM(w,4);
+        mpz_set_si(z->big.big_num, x);
+        mpz_set_si(w->big.big_num, y);
+        mpz_mu(z->big.big_num, z->big.big_num, w->big.big_num);
+#endif
+        {
+                cl_object y = big_normalize(z);
+                if (y == z) y = _ecl_big_copy(z);
+                return y;
+        }
+}
+
 cl_object
 _ecl_big_times_big(cl_object a, cl_object b)
 {
index db8b1b6..e13b9dc 100644 (file)
@@ -123,6 +123,14 @@ _ecl_big_plus_fix(cl_object x, cl_fixnum y)
         z->big.big_num = x->big.big_num + y;
        return big_normalize(z);
 }
+cl_object
+_ecl_fix_times_fix(cl_fixnum x, cl_fixnum y)
+{
+       cl_object z = ecl_alloc_object(t_bignum);
+        z->big.big_num = x * y;
+       return big_normalize(z);
+}
+
 
 cl_object
 _ecl_big_negate(cl_object x)
index 0574677..4021c4f 100644 (file)
 @)
 
 cl_object
-fixnum_times(cl_fixnum i, cl_fixnum j)
-{
-       cl_object x = _ecl_big_register0();
-        _ecl_big_set_si(x, i);
-        _ecl_big_mul_si(x, x, j);
-       return _ecl_big_register_normalize(x);
-}
-
-cl_object
 ecl_times(cl_object x, cl_object y)
 {
        cl_object z, z1;
@@ -49,7 +40,7 @@ ecl_times(cl_object x, cl_object y)
        case t_fixnum:
                switch (type_of(y)) {
                case t_fixnum:
-                       return fixnum_times(fix(x),fix(y));
+                       return _ecl_fix_times_fix(fix(x),fix(y));
                case t_bignum:
                        return _ecl_big_times_fix(y, fix(x));
                case t_ratio:
index 37f96cb..5f80bf7 100755 (executable)
@@ -376,6 +376,7 @@ extern ECL_API void ecl_clear_compiler_properties(cl_object sym);
 #define _ecl_big_register0()   ecl_process_env()->big_register[0]
 #define _ecl_big_register1()   ecl_process_env()->big_register[1]
 #define _ecl_big_register2()   ecl_process_env()->big_register[2]
+extern ECL_API cl_object _ecl_fix_times_fix(cl_fixnum x, cl_fixnum y);
 extern ECL_API cl_object _ecl_big_register_copy(cl_object x);
 extern ECL_API cl_object _ecl_big_register_normalize(cl_object x);
 extern ECL_API cl_object _ecl_big_times_fix(cl_object x, cl_fixnum y);
@@ -974,7 +975,6 @@ extern ECL_API cl_object cl_N _ARGS((cl_narg narg, cl_object num, ...));
 extern ECL_API cl_object cl_gcd _ARGS((cl_narg narg, ...));
 extern ECL_API cl_object cl_lcm _ARGS((cl_narg narg, ...));
 
-extern ECL_API cl_object fixnum_times(cl_fixnum i, cl_fixnum j);
 extern ECL_API cl_object ecl_times(cl_object x, cl_object y);
 extern ECL_API cl_object number_to_complex(cl_object x);
 extern ECL_API cl_object ecl_plus(cl_object x, cl_object y);