src/N.GCD.cpp

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

Hosted by SourceForge.net Logo