00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 class IntegerOps;
00034 typedef unsigned int Digit;
00035
00036 class Integer: ValueObj {
00037 private:
00038 int _signed_length;
00039 Digit _first_digit;
00040 Digit _debug[9999];
00041
00042 int length() const { return _signed_length < 0 ? -_signed_length : _signed_length; }
00043 void set_length(int l) { _signed_length = l; }
00044 Digit* digits() const { return (Digit*)&_first_digit; }
00045 Digit& operator[] (int i) const { return digits()[i]; }
00046
00047 static int length_to_size_in_bytes(int l) { return sizeof(int) + l*sizeof(Digit); }
00048
00049 int length_in_bits() const;
00050
00051 public:
00052 int signum() const { return _signed_length; }
00053 bool is_zero() const { return signum() == 0; }
00054 bool is_not_zero() const { return signum() != 0; }
00055 bool is_positive() const { return signum() > 0; }
00056 bool is_negative() const { return signum() < 0; }
00057
00058 bool is_odd() const { return is_not_zero() && (_first_digit & 1) == 1; }
00059 bool is_even() const { return !is_odd(); }
00060
00061 bool is_valid() const { return is_zero() || operator[](length() - 1) != 0; }
00062 int size_in_bytes() const { return length_to_size_in_bytes(length()); }
00063
00064 int as_int (bool& ok) const;
00065 double as_double(bool& ok) const;
00066 smiOop as_smi (bool& ok) const;
00067
00068 void print();
00069
00070 friend class IntegerOps;
00071 };
00072
00073
00074
00075
00076
00077
00078
00079 class IntegerOps: AllStatic {
00080 private:
00081 static inline Digit as_Digit(char c);
00082 static inline char as_char(int i);
00083
00084 static inline Digit xpy ( Digit x, Digit y, Digit& carry);
00085 static inline Digit xmy ( Digit x, Digit y, Digit& carry);
00086 static inline Digit axpy(Digit a, Digit x, Digit y, Digit& carry);
00087 static inline Digit xdy ( Digit x, Digit y, Digit& carry);
00088
00089 static Digit power(Digit x, int n);
00090 static Digit max_power(Digit x);
00091
00092 static int unsigned_add_result_length(Integer& x, Integer& y) { return max(x.length(), y.length()) + 1; }
00093 static int unsigned_sub_result_length(Integer& x, Integer& y) { return x.length(); }
00094 static int unsigned_mul_result_length(Integer& x, Integer& y) { return x.is_zero() || y.is_zero() ? 0 : x.length() + y.length(); }
00095 static int unsigned_quo_result_length(Integer& x, Integer& y) { return max(x.length() - y.length() + 1, 0); }
00096 static int unsigned_rem_result_length(Integer& x, Integer& y) { return y.length(); }
00097
00098 static void unsigned_add(Integer& x, Integer& y, Integer& z);
00099 static void unsigned_sub(Integer& x, Integer& y, Integer& z);
00100 static void unsigned_mul(Integer& x, Integer& y, Integer& z);
00101 static void unsigned_quo(Integer& x, Integer& y, Integer& z);
00102 static void unsigned_rem(Integer& x, Integer& y, Integer& z);
00103 static int unsigned_cmp(Integer& x, Integer& y );
00104
00105 static Digit scale(Digit* array, Digit factor, int length);
00106 static Digit* qr_decomposition(Integer& x, Integer& y);
00107 static Digit last_digit (Integer& x, Digit b);
00108 static void first_digit(Integer& x, Digit b, Digit c);
00109
00110 public:
00111
00112
00113 static int add_result_size_in_bytes(Integer& x, Integer& y);
00114 static int sub_result_size_in_bytes(Integer& x, Integer& y);
00115 static int mul_result_size_in_bytes(Integer& x, Integer& y);
00116 static int quo_result_size_in_bytes(Integer& x, Integer& y);
00117 static int rem_result_size_in_bytes(Integer& x, Integer& y);
00118 static int div_result_size_in_bytes(Integer& x, Integer& y);
00119 static int mod_result_size_in_bytes(Integer& x, Integer& y);
00120
00121 static int and_result_size_in_bytes(Integer& x, Integer& y);
00122 static int or_result_size_in_bytes (Integer& x, Integer& y);
00123 static int xor_result_size_in_bytes(Integer& x, Integer& y);
00124 static int ash_result_size_in_bytes(Integer& x, int n);
00125
00126 static int copy_result_size_in_bytes(Integer& x);
00127 static int int_to_Integer_result_size_in_bytes(int i);
00128 static int double_to_Integer_result_size_in_bytes(double x);
00129 static int string_to_Integer_result_size_in_bytes(char* s, int base);
00130 static int Integer_to_string_result_size_in_bytes(Integer& x, int base);
00131
00132
00133 static void add(Integer& x, Integer& y, Integer& z);
00134 static void sub(Integer& x, Integer& y, Integer& z);
00135 static void mul(Integer& x, Integer& y, Integer& z);
00136 static void quo(Integer& x, Integer& y, Integer& z);
00137 static void rem(Integer& x, Integer& y, Integer& z);
00138 static void div(Integer& x, Integer& y, Integer& z);
00139 static void mod(Integer& x, Integer& y, Integer& z);
00140
00141 static void and(Integer& x, Integer& y, Integer& z);
00142 static void or (Integer& x, Integer& y, Integer& z);
00143 static void xor(Integer& x, Integer& y, Integer& z);
00144 static void ash(Integer& x, int n, Integer& z);
00145
00146 static int cmp(Integer& x, Integer& y );
00147
00148 static void abs(Integer& x);
00149 static void neg(Integer& x);
00150
00151
00152 static void copy(Integer& x, Integer& z);
00153 static void int_to_Integer(int i, Integer& z);
00154 static void double_to_Integer(double x, Integer& z);
00155 static void string_to_Integer(char* s, int base, Integer& z);
00156 static void Integer_to_string(Integer& x, int base, char* s);
00157
00158
00159 static void self_test();
00160 };