00001 #include <symbolism/N.h> 00002 00003 namespace symbolism { 00004 namespace ring { 00005 00007 void N::gcd_large_large(const N& a, const N& b) 00008 { 00009 // Find the multiplicities of the factor two 00010 size_t a_twos = a.two_multiplicity_large(); 00011 size_t b_twos = b.two_multiplicity_large(); 00012 00013 // Get the odd parts of the numbers 00014 // and provide copies for the destructive gmp algo's 00015 N a_odd, b_odd; 00016 a_odd.right_shift_large(a, a_twos); 00017 b_odd.right_shift_large(b, b_twos); 00018 size_t s; 00019 00020 // TODO: Comparisson malfunctions 00021 if(b_odd > a_odd) 00022 { 00023 swap(a_odd, b_odd); 00024 } 00025 00026 reserve(b_odd.size); 00027 s = mpn_gcd(limbs(), a_odd.limbs(), a_odd.size + 1, b_odd.limbs(), b_odd.size + 1); 00028 00029 truncate(s - 1); 00030 left_shift(std::min(a_twos, b_twos)); 00031 } 00032 00033 00034 void N::gcd_large_small(const N& a, const limb_t b) 00035 { 00036 if(fast_false(b == 0)) 00037 { 00038 set(a); 00039 } 00040 else 00041 { 00042 reserve(0); 00043 limb = mpn_gcd_1(a.data, a.size + 1, b); 00044 } 00045 } 00046 00047 void N::gcd_small_small(const limb_t u, const limb_t v) 00048 { 00049 reserve(0); 00050 if(u ==0 || v == 0) 00051 { 00052 limb = u | v; 00053 } 00054 else 00055 { 00056 limb_t a = u; 00057 limb_t b = v; 00058 00059 size_t a_twos = __builtin_ctzll(a); 00060 size_t b_twos = __builtin_ctzll(b); 00061 size_t twos = std::min(a_twos, b_twos); 00062 a >>= a_twos; 00063 00064 // From here on, a is always odd. 00065 do 00066 { 00067 b >>= __builtin_ctzll(b); 00068 00069 // Now a and b are both odd, so diff(a, b) is even. 00070 // Let a = min(a, b), b = diff(a, b)/2. */ 00071 if (a <= b) 00072 { 00073 b -= a; 00074 } 00075 else 00076 { 00077 limb_t diff = a - b; 00078 a = b; 00079 b = diff; 00080 } 00081 b >>= 1; 00082 } 00083 while (b != 0); 00084 limb = a << twos; 00085 } 00086 } 00087 00088 void N::gcd_small_small(const limb_t b) 00089 { 00090 } 00091 00092 void N::gcd_large_large(const N& b) 00093 { 00094 } 00095 00096 void N::gcd_large_small(const limb_t b) 00097 { 00098 } 00099 00100 void N::gcd_small_large(const N& b) 00101 { 00102 } 00103 00104 }}
Copyright © 2007-2008 Remco Bloemen.
Generated on Tue Jan 22 17:35:31 2008 for symbolism by doxygen 1.5.4