include/symbolism/N.h

00001 #pragma once
00002 #include <iostream>
00003 #include <gmp.h>
00004 #include <cassert>
00005 #include <symbolism/exception.h>
00006 
00007 namespace symbolism {
00008 namespace ring {
00009 
00161 class N
00162 {
00163     public:
00164 
00166 
00168         typedef mp_limb_t limb_t;
00169 
00171         typedef long unsigned int size_t;
00172 
00174         static const int bits_per_limb = 8 * sizeof(limb_t);
00175 
00177         size_t size;
00178 
00180         union
00181         {
00183             limb_t  limb;
00184 
00190             limb_t* data;
00191         };
00192 
00194         inline N();
00195         inline N(const N& copy);
00196         inline N(const limb_t value);
00197         inline ~N();
00198 
00200         inline limb_t* limbs();
00201         inline const limb_t* limbs() const;
00202         inline void set(const N& copy);
00203         inline void set(const limb_t value);
00204         inline friend void swap(N& a, N& b);
00205         inline N& operator=(const N& copy);
00206         inline N& operator=(const limb_t value);
00207         inline friend size_t max(const size_t a, const size_t b);
00208         inline void reserve(size_t newsize);
00209         inline void resize(size_t newsize);
00210         inline void truncate(size_t newsize);
00211         inline void normalize();
00212 
00214         inline bool is_zero() const;
00215         inline bool is_one() const;
00216         inline int compare(const N& a) const;
00217         inline int compare(const limb_t a) const;
00218         inline friend bool operator==(const N& a, const N& b);
00219         inline friend bool operator!=(const N& a, const N& b);
00220         inline friend bool operator> (const N& a, const N& b);
00221         inline friend bool operator>=(const N& a, const N& b);
00222         inline friend bool operator< (const N& a, const N& b);
00223         inline friend bool operator<=(const N& a, const N& b);
00224 
00226         inline size_t two_multiplicity() const;
00227         inline void binary_not(const N& a);
00228         inline void binary_not();
00229         inline void binary_and(const N& a, const N& b);
00230         inline void binary_and(const N& a);
00231         inline void binary_or(const N& a, const N& b);
00232         inline void binary_or(const N& a);
00233         inline void binary_xor(const N& a, const N& b);
00234         inline void binary_xor(const N& a);
00235         inline void left_shift(const N& a, unsigned int count);
00236         inline void left_shift(unsigned int count);
00237         inline void right_shift(const N& a, unsigned int count);
00238         inline void right_shift(unsigned int count);
00239         inline friend N operator~(const N& a);
00240         inline friend N operator&(const N& a, const N& b);
00241         inline friend N operator|(const N& a, const N& b);
00242         inline friend N operator<<(const N& a, unsigned int count);
00243         inline friend N operator>>(const N& a, unsigned int count);
00244         inline N& operator<<=(const limb_t count);
00245         inline N& operator>>=(const limb_t cout);
00246         inline N& operator&=(const N& a);
00247         inline N& operator|=(const N& a);
00248 
00250         inline void add(const N& a, const N& b);
00251         inline void add(const N& a);
00252         inline void add_one();
00253         inline friend N operator+(const N& a, const N& b);
00254         inline N& operator+=(const N& rhs);
00255         inline N& operator++();
00256         inline N operator++(int);
00257 
00259         inline void sub(const N& a, const N& b);
00260         inline void sub(const N& a);
00261         inline void sub_one();
00262         inline friend N operator-(const N& a, const N& b);
00263         inline N& operator-=(const N& rhs);
00264         inline N& operator--();
00265         inline N operator--(int);
00266 
00268         inline void mul(const N& a, const N& b);
00269         inline void mul(const N& a);
00270         inline friend N operator*(const N& a, const N& b);
00271         inline N& operator*=(const N& rhs);
00272 
00274         inline void addmul(const N& a, const limb_t b);
00275         inline void submul(const N& a, const limb_t b);
00276 
00278         inline void exact_div(const N& a, const N& b);
00279         inline void exact_div(const N& a);
00280         inline void div(N& rem, const N& a, const N& b);
00281         inline void div(N& rem, const N& a);
00282         inline void quo(const N& a, const N& b);
00283         inline void quo(const N& a);
00284         inline void rem(const N& a, const N& b);
00285         inline void rem(const N& a);
00286         inline friend N operator/(const N& a, const N& b);
00287         inline N& operator/=(const N& rhs);
00288         inline friend N operator%(const N& a, const N& b);
00289         inline N& operator%=(const N& rhs);
00290         inline friend N div(N& rem, const N& a, const N& b);
00291         inline friend N div_exact(const N& a, const N& b);
00292         inline friend N quo(const N& a, const N& b);
00293         inline friend N rem(const N& a, const N& b);
00294 
00296         inline void gcd(const N& a, const N& b);
00297         inline void gcd(const N& b);
00298         inline void extended_gcd(N& x, N& y, const N& a, const N& b);
00299         inline void lcm(const N& a, const N& b);
00300         inline void lcm(const N& b);
00301 
00303         inline friend N gcd(const N& a, const N& b);
00304 
00306         void random(const size_t newsize);
00307         void random2(const size_t newsize);
00308 
00310         inline limb_t to_int() const;
00311         std::string to_binary() const;
00312         std::string to_hexadecimal() const;
00313         std::string to_decimal() const;
00314         std::string to_english() const;
00315         void write_english(std::ostream& out) const;
00316         inline friend std::ostream& operator<<(std::ostream& out, const N& n);
00317 
00318     public:
00320         void reserve_small(size_t newsize);
00321         void reserve_large(size_t newsize);
00322         void resize_small(size_t newsize);
00323         void resize_large(size_t newsize);
00324         void truncate_large(size_t newsize);
00325         void normalize_large();
00326 
00328         inline size_t two_multiplicity_large() const;
00329         inline size_t two_multiplicity_small() const;
00330         void left_shift_large(const N& a, unsigned int count);
00331         inline void left_shift_small(const limb_t a, unsigned int count);
00332         void left_shift_large(unsigned int count);
00333         inline void left_shift_small(unsigned int count);
00334         void right_shift_large(const N& a, unsigned int count);
00335         inline void right_shift_small(const limb_t a, unsigned int count);
00336         void right_shift_large(unsigned int count);
00337         inline void right_shift_small(unsigned int count);
00338 
00340         inline void add_carry_small(const limb_t carry = 1);
00341         inline void add_carry_large(const limb_t carry = 1);
00342         void add_large_large(const N& a, const N& b);
00343         void add_large_small(const N& a, const limb_t b);
00344         inline void add_small_small(const limb_t a, const limb_t b);
00345         void add_large_large(const N& a);
00346         void add_large_small(const limb_t a);
00347         void add_small_large(const N& a);
00348         inline void add_small_small(const limb_t a);
00349         void add_one_large();
00350         inline void add_one_small();
00351 
00353         void sub_large_large(const N& a, const N& b);
00354         void sub_large_small(const N& a, const limb_t b);
00355         inline void sub_small_small(const limb_t a, const limb_t b);
00356         void sub_large_large(const N& a);
00357         void sub_large_small(const limb_t a);
00358         inline void sub_small_small(const limb_t a);
00359         void sub_one_large();
00360         inline void sub_one_small();
00361 
00363         void mul_large_large(const N& a, const N& b);
00364         void mul_large_small(const N& a, const limb_t b);
00365         inline void mul_small_small(const limb_t a, const limb_t b);
00366         void mul_large_large(const N& a);
00367         void mul_large_small(const limb_t a);
00368         void mul_small_large(const N& a);
00369         inline void mul_small_small(const limb_t a);
00370 
00372         void addmul_large_large(const N& a, const limb_t b);
00373         void addmul_large_small(const limb_t a, const limb_t b);
00374         void addmul_small_large(const N& a, const limb_t b);
00375         inline void addmul_small_small(const limb_t a, const limb_t b);
00376         void submul_large_large(const N& a, const limb_t b);
00377         void submul_large_small(const limb_t a, const limb_t b);
00378         void submul_small_large(const N& a, const limb_t b);
00379         inline void submul_small_small(const limb_t a, const limb_t b);
00380 
00382         void exact_div_large_large(const N& a, const N& b);
00383         void exact_div_large_small(const N& a, const limb_t b);
00384         inline void exact_div_small_small(const limb_t a, const limb_t b);
00385         void exact_div_large_large(const N& b);
00386         void exact_div_large_small(const limb_t b);
00387         inline void exact_div_small_small(const limb_t b);
00388         void div_large_large(N& rem, const N& a, const N& b);
00389         void div_large_small(N& rem, const N& a, const limb_t b);
00390         void div_small_large(N& rem, const limb_t a, const N& b);
00391         inline void div_small_small(N& rem, const limb_t a, const limb_t b);
00392         void div_large_large(N& rem, const N& b);
00393         void div_large_small(N& rem, const limb_t b);
00394         void div_small_large(N& rem, const N& b);
00395         inline void div_small_small(N& rem, const limb_t b);
00396         void quo_large_large(const N& a, const N& b);
00397         void quo_large_small(const N& a, const limb_t b);
00398         void quo_small_large(const limb_t a, const N& b);
00399         inline void quo_small_small(const limb_t a, const limb_t b);
00400         void quo_large_large(const N& b);
00401         void quo_large_small(const limb_t b);
00402         void quo_small_large(const N& b);
00403         inline void quo_small_small(const limb_t b);
00404         void rem_large_large(const N& a, const N& b);
00405         void rem_large_small(const N& a, const limb_t b);
00406         void rem_small_large(const limb_t a, const N& b);
00407         inline void rem_small_small(const limb_t a, const limb_t b);
00408         void rem_large_large(const N& b);
00409         void rem_large_small(const limb_t b);
00410         void rem_small_large(const N& b);
00411         inline void rem_small_small(const limb_t b);
00412 
00414         void gcd_large_large(const N& a, const N& b);
00415         void gcd_large_small(const N& a, const limb_t b);
00416         void gcd_small_small(const limb_t a, const limb_t b);
00417         void gcd_large_large(const N& b);
00418         void gcd_large_small(const limb_t b);
00419         void gcd_small_large(const N& b);
00420         void gcd_small_small(const limb_t b);
00421 
00423 };
00424 
00425 class not_implemented_exception: public utility::exception
00426 {
00427     DECLARE_EXCEPTION_CONSTRUCTORS(not_implemented_exception);
00428 
00429     virtual const std::string description() const throw()
00430     {
00431         return "The operation you requested has not been implemented"
00432                " yet. You can help Symbolism by implementing it!";
00433     }
00434 };
00435 
00436 class can_not_shrink_exception: public utility::exception
00437 {
00438     DECLARE_EXCEPTION_CONSTRUCTORS(can_not_shrink_exception);
00439 
00440     virtual const std::string description() const throw()
00441     {
00442         return "The number of limbs can not be lowered without"
00443                " changing the numbers value. Consider using"
00444                " N::truncate or N::reserve.";
00445     }
00446 };
00447 
00448 class result_negative_exception: public utility::exception
00449 {
00450     DECLARE_EXCEPTION_CONSTRUCTORS(result_negative_exception);
00451 
00452     virtual const std::string description() const throw()
00453     {
00454         return "The result of this operation is negative, while"
00455                " the datatype can only contain positive numbers.";
00456     }
00457 };
00458 
00459 class inexact_division_exception: public utility::exception
00460 {
00461     DECLARE_EXCEPTION_CONSTRUCTORS(inexact_division_exception);
00462 
00463     virtual const std::string description() const throw()
00464     {
00465         return "The exact division that was requested has left"
00466                " a non-zero remainder.";
00467     }
00468 };
00469 
00470 class division_by_zero_exception: public utility::exception
00471 {
00472     DECLARE_EXCEPTION_CONSTRUCTORS(division_by_zero_exception);
00473 
00474     virtual const std::string description() const throw()
00475     {
00476         return "A division has been requested with a zero"
00477                " denominator.";
00478     }
00479 };
00480 
00481 // Macro to optimize branch prediction
00482 #define fast_true(a) __builtin_expect(a, 1)
00483 #define fast_false(a) __builtin_expect(a, 0)
00484 
00485 // Optimize branches for small numbers
00486 #define this_small fast_true(size == 0)
00487 #define is_small(a) fast_true(a.size == 0)
00488 
00489 #include "N.Constructors.h"
00490 #include "N.Accessors.h"
00491 #include "N.Size.h"
00492 #include "N.Comparisson.h"
00493 #include "N.Binary.h"
00494 #include "N.Assignment.h"
00495 #include "N.Addition.h"
00496 #include "N.Substraction.h"
00497 #include "N.Multiplication.h"
00498 #include "N.Division.h"
00499 #include "N.AddSubmul.h"
00500 #include "N.GCD.h"
00501 #include "N.Random.h"
00502 #include "N.Conversion.h"
00503 
00504 }}

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