yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
BigInteger.cc
Go to the documentation of this file.
1 #include "BigInteger.hh"
2 
4  // Calls like a = a have no effect
5  if (this == &x)
6  return;
7  // Copy sign
8  sign = x.sign;
9  // Copy the rest
10  mag = x.mag;
11 }
12 
13 BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) {
14  switch (s) {
15  case zero:
16  if (!mag.isZero())
17  throw "BigInteger::BigInteger(const Blk *, Index, Sign): Cannot use a sign of zero with a nonzero magnitude";
18  sign = zero;
19  break;
20  case positive:
21  case negative:
22  // If the magnitude is zero, force the sign to zero.
23  sign = mag.isZero() ? zero : s;
24  break;
25  default:
26  /* g++ seems to be optimizing out this case on the assumption
27  * that the sign is a valid member of the enumeration. Oh well. */
28  throw "BigInteger::BigInteger(const Blk *, Index, Sign): Invalid sign";
29  }
30 }
31 
32 BigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) {
33  switch (s) {
34  case zero:
35  if (!mag.isZero())
36  throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Cannot use a sign of zero with a nonzero magnitude";
37  sign = zero;
38  break;
39  case positive:
40  case negative:
41  // If the magnitude is zero, force the sign to zero.
42  sign = mag.isZero() ? zero : s;
43  break;
44  default:
45  /* g++ seems to be optimizing out this case on the assumption
46  * that the sign is a valid member of the enumeration. Oh well. */
47  throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Invalid sign";
48  }
49 }
50 
51 /* CONSTRUCTION FROM PRIMITIVE INTEGERS
52  * Same idea as in BigUnsigned.cc, except that negative input results in a
53  * negative BigInteger instead of an exception. */
54 
55 // Done longhand to let us use initialization.
56 BigInteger::BigInteger(unsigned long x) : mag(x) { sign = mag.isZero() ? zero : positive; }
57 BigInteger::BigInteger(unsigned int x) : mag(x) { sign = mag.isZero() ? zero : positive; }
58 BigInteger::BigInteger(unsigned short x) : mag(x) { sign = mag.isZero() ? zero : positive; }
59 
60 // For signed input, determine the desired magnitude and sign separately.
61 
62 namespace {
63  template <class X, class UX>
64  BigInteger::Blk magOf(X x) {
65  /* UX(...) cast needed to stop short(-2^15), which negates to
66  * itself, from sign-extending in the conversion to Blk. */
67  return BigInteger::Blk(x < 0 ? UX(-x) : x);
68  }
69  template <class X>
70  BigInteger::Sign signOf(X x) {
71  return (x == 0) ? BigInteger::zero
72  : (x > 0) ? BigInteger::positive
74  }
75 }
76 
77 BigInteger::BigInteger(long x) : sign(signOf(x)), mag(magOf<long , unsigned long >(x)) {}
78 BigInteger::BigInteger(int x) : sign(signOf(x)), mag(magOf<int , unsigned int >(x)) {}
79 BigInteger::BigInteger(short x) : sign(signOf(x)), mag(magOf<short, unsigned short>(x)) {}
80 
81 // CONVERSION TO PRIMITIVE INTEGERS
82 
83 /* Reuse BigUnsigned's conversion to an unsigned primitive integer.
84  * The friend is a separate function rather than
85  * BigInteger::convertToUnsignedPrimitive to avoid requiring BigUnsigned to
86  * declare BigInteger. */
87 template <class X>
89  return a.convertToPrimitive<X>();
90 }
91 
92 template <class X>
94  if (sign == negative)
95  throw "BigInteger::to<Primitive>: "
96  "Cannot convert a negative integer to an unsigned type";
97  else
98  return convertBigUnsignedToPrimitiveAccess<X>(mag);
99 }
100 
101 /* Similar to BigUnsigned::convertToPrimitive, but split into two cases for
102  * nonnegative and negative numbers. */
103 template <class X, class UX>
105  if (sign == zero)
106  return 0;
107  else if (mag.getLength() == 1) {
108  // The single block might fit in an X. Try the conversion.
109  Blk b = mag.getBlock(0);
110  if (sign == positive) {
111  X x = X(b);
112  if (x >= 0 && Blk(x) == b)
113  return x;
114  } else {
115  X x = -X(b);
116  /* UX(...) needed to avoid rejecting conversion of
117  * -2^15 to a short. */
118  if (x < 0 && Blk(UX(-x)) == b)
119  return x;
120  }
121  // Otherwise fall through.
122  }
123  throw "BigInteger::to<Primitive>: "
124  "Value is too big to fit in the requested type";
125 }
126 
127 unsigned long BigInteger::toUnsignedLong () const { return convertToUnsignedPrimitive<unsigned long > (); }
128 unsigned int BigInteger::toUnsignedInt () const { return convertToUnsignedPrimitive<unsigned int > (); }
129 unsigned short BigInteger::toUnsignedShort() const { return convertToUnsignedPrimitive<unsigned short> (); }
130 long BigInteger::toLong () const { return convertToSignedPrimitive <long , unsigned long> (); }
131 int BigInteger::toInt () const { return convertToSignedPrimitive <int , unsigned int> (); }
132 short BigInteger::toShort () const { return convertToSignedPrimitive <short, unsigned short>(); }
133 
134 // COMPARISON
136  // A greater sign implies a greater number
137  if (sign < x.sign)
138  return less;
139  else if (sign > x.sign)
140  return greater;
141  else switch (sign) {
142  // If the signs are the same...
143  case zero:
144  return equal; // Two zeros are equal
145  case positive:
146  // Compare the magnitudes
147  return mag.compareTo(x.mag);
148  case negative:
149  // Compare the magnitudes, but return the opposite result
150  return CmpRes(-mag.compareTo(x.mag));
151  default:
152  throw "BigInteger internal error";
153  }
154 }
155 
156 /* COPY-LESS OPERATIONS
157  * These do some messing around to determine the sign of the result,
158  * then call one of BigUnsigned's copy-less operations. */
159 
160 // See remarks about aliased calls in BigUnsigned.cc .
161 #define DTRT_ALIASED(cond, op) \
162  if (cond) { \
163  BigInteger tmpThis; \
164  tmpThis.op; \
165  *this = tmpThis; \
166  return; \
167  }
168 
169 void BigInteger::add(const BigInteger &a, const BigInteger &b) {
170  DTRT_ALIASED(this == &a || this == &b, add(a, b));
171  // If one argument is zero, copy the other.
172  if (a.sign == zero)
173  operator =(b);
174  else if (b.sign == zero)
175  operator =(a);
176  // If the arguments have the same sign, take the
177  // common sign and add their magnitudes.
178  else if (a.sign == b.sign) {
179  sign = a.sign;
180  mag.add(a.mag, b.mag);
181  } else {
182  // Otherwise, their magnitudes must be compared.
183  switch (a.mag.compareTo(b.mag)) {
184  case equal:
185  // If their magnitudes are the same, copy zero.
186  mag = 0;
187  sign = zero;
188  break;
189  // Otherwise, take the sign of the greater, and subtract
190  // the lesser magnitude from the greater magnitude.
191  case greater:
192  sign = a.sign;
193  mag.subtract(a.mag, b.mag);
194  break;
195  case less:
196  sign = b.sign;
197  mag.subtract(b.mag, a.mag);
198  break;
199  }
200  }
201 }
202 
203 void BigInteger::subtract(const BigInteger &a, const BigInteger &b) {
204  // Notice that this routine is identical to BigInteger::add,
205  // if one replaces b.sign by its opposite.
206  DTRT_ALIASED(this == &a || this == &b, subtract(a, b));
207  // If a is zero, copy b and flip its sign. If b is zero, copy a.
208  if (a.sign == zero) {
209  mag = b.mag;
210  // Take the negative of _b_'s, sign, not ours.
211  // Bug pointed out by Sam Larkin on 2005.03.30.
212  sign = Sign(-b.sign);
213  } else if (b.sign == zero)
214  operator =(a);
215  // If their signs differ, take a.sign and add the magnitudes.
216  else if (a.sign != b.sign) {
217  sign = a.sign;
218  mag.add(a.mag, b.mag);
219  } else {
220  // Otherwise, their magnitudes must be compared.
221  switch (a.mag.compareTo(b.mag)) {
222  // If their magnitudes are the same, copy zero.
223  case equal:
224  mag = 0;
225  sign = zero;
226  break;
227  // If a's magnitude is greater, take a.sign and
228  // subtract a from b.
229  case greater:
230  sign = a.sign;
231  mag.subtract(a.mag, b.mag);
232  break;
233  // If b's magnitude is greater, take the opposite
234  // of b.sign and subtract b from a.
235  case less:
236  sign = Sign(-b.sign);
237  mag.subtract(b.mag, a.mag);
238  break;
239  }
240  }
241 }
242 
243 void BigInteger::multiply(const BigInteger &a, const BigInteger &b) {
244  DTRT_ALIASED(this == &a || this == &b, multiply(a, b));
245  // If one object is zero, copy zero and return.
246  if (a.sign == zero || b.sign == zero) {
247  sign = zero;
248  mag = 0;
249  return;
250  }
251  // If the signs of the arguments are the same, the result
252  // is positive, otherwise it is negative.
253  sign = (a.sign == b.sign) ? positive : negative;
254  // Multiply the magnitudes.
255  mag.multiply(a.mag, b.mag);
256 }
257 
258 /*
259  * DIVISION WITH REMAINDER
260  * Please read the comments before the definition of
261  * `BigUnsigned::divideWithRemainder' in `BigUnsigned.cc' for lots of
262  * information you should know before reading this function.
263  *
264  * Following Knuth, I decree that x / y is to be
265  * 0 if y==0 and floor(real-number x / y) if y!=0.
266  * Then x % y shall be x - y*(integer x / y).
267  *
268  * Note that x = y * (x / y) + (x % y) always holds.
269  * In addition, (x % y) is from 0 to y - 1 if y > 0,
270  * and from -(|y| - 1) to 0 if y < 0. (x % y) = x if y = 0.
271  *
272  * Examples: (q = a / b, r = a % b)
273  * a b q r
274  * === === === ===
275  * 4 3 1 1
276  * -4 3 -2 2
277  * 4 -3 -2 -2
278  * -4 -3 1 -1
279  */
281  // Defend against aliased calls;
282  // same idea as in BigUnsigned::divideWithRemainder .
283  if (this == &q)
284  throw "BigInteger::divideWithRemainder: Cannot write quotient and remainder into the same variable";
285  if (this == &b || &q == &b) {
286  BigInteger tmpB(b);
287  divideWithRemainder(tmpB, q);
288  return;
289  }
290 
291  // Division by zero gives quotient 0 and remainder *this
292  if (b.sign == zero) {
293  q.mag = 0;
294  q.sign = zero;
295  return;
296  }
297  // 0 / b gives quotient 0 and remainder 0
298  if (sign == zero) {
299  q.mag = 0;
300  q.sign = zero;
301  return;
302  }
303 
304  // Here *this != 0, b != 0.
305 
306  // Do the operands have the same sign?
307  if (sign == b.sign) {
308  // Yes: easy case. Quotient is zero or positive.
309  q.sign = positive;
310  } else {
311  // No: harder case. Quotient is negative.
312  q.sign = negative;
313  // Decrease the magnitude of the dividend by one.
314  mag--;
315  /*
316  * We tinker with the dividend before and with the
317  * quotient and remainder after so that the result
318  * comes out right. To see why it works, consider the following
319  * list of examples, where A is the magnitude-decreased
320  * a, Q and R are the results of BigUnsigned division
321  * with remainder on A and |b|, and q and r are the
322  * final results we want:
323  *
324  * a A b Q R q r
325  * -3 -2 3 0 2 -1 0
326  * -4 -3 3 1 0 -2 2
327  * -5 -4 3 1 1 -2 1
328  * -6 -5 3 1 2 -2 0
329  *
330  * It appears that we need a total of 3 corrections:
331  * Decrease the magnitude of a to get A. Increase the
332  * magnitude of Q to get q (and make it negative).
333  * Find r = (b - 1) - R and give it the desired sign.
334  */
335  }
336 
337  // Divide the magnitudes.
339 
340  if (sign != b.sign) {
341  // More for the harder case (as described):
342  // Increase the magnitude of the quotient by one.
343  q.mag++;
344  // Modify the remainder.
345  mag.subtract(b.mag, mag);
346  mag--;
347  }
348 
349  // Sign of the remainder is always the sign of the divisor b.
350  sign = b.sign;
351 
352  // Set signs to zero as necessary. (Thanks David Allen!)
353  if (mag.isZero())
354  sign = zero;
355  if (q.mag.isZero())
356  q.sign = zero;
357 
358  // WHEW!!!
359 }
360 
361 // Negation
363  DTRT_ALIASED(this == &a, negate(a));
364  // Copy a's magnitude
365  mag = a.mag;
366  // Copy the opposite of a.sign
367  sign = Sign(-a.sign);
368 }
369 
370 // INCREMENT/DECREMENT OPERATORS
371 
372 // Prefix increment
374  if (sign == negative) {
375  mag--;
376  if (mag == 0)
377  sign = zero;
378  } else {
379  mag++;
380  sign = positive; // if not already
381  }
382 }
383 
384 // Postfix increment: same as prefix
386  operator ++();
387 }
388 
389 // Prefix decrement
391  if (sign == positive) {
392  mag--;
393  if (mag == 0)
394  sign = zero;
395  } else {
396  mag++;
397  sign = negative;
398  }
399 }
400 
401 // Postfix decrement: same as prefix
403  operator --();
404 }
405 
unsigned long toUnsignedLong() const
Definition: BigInteger.cc:127
BigUnsigned mag
Definition: BigInteger.hh:28
BigUnsigned::CmpRes CmpRes
Definition: BigInteger.hh:18
void negate(const BigInteger &a)
Definition: BigInteger.cc:362
CmpRes compareTo(const BigUnsigned &x) const
Definition: BigUnsigned.cc:69
X convertToPrimitive() const
Definition: BigUnsigned.hh:387
static const CmpRes greater
Definition: BigInteger.hh:22
#define X(_item)
void divideWithRemainder(const BigUnsigned &b, BigUnsigned &q)
Definition: BigUnsigned.cc:382
CmpRes compareTo(const BigInteger &x) const
Definition: BigInteger.cc:135
void operator=(const BigInteger &x)
Definition: BigInteger.cc:3
bool sign(Lit p)
Definition: SolverTypes.h:66
BigUnsigned::Index Index
Definition: BigInteger.hh:17
void operator++()
Definition: BigInteger.cc:373
Index getLength() const
void add(const BigUnsigned &a, const BigUnsigned &b)
Definition: BigUnsigned.cc:124
unsigned short toUnsignedShort() const
Definition: BigInteger.cc:129
long toLong() const
Definition: BigInteger.cc:130
X convertToUnsignedPrimitive() const
Definition: BigInteger.cc:93
bool isZero() const
Definition: BigUnsigned.hh:97
void subtract(const BigUnsigned &a, const BigUnsigned &b)
Definition: BigUnsigned.cc:184
short toShort() const
Definition: BigInteger.cc:132
static const CmpRes equal
Definition: BigInteger.hh:21
void add(const BigInteger &a, const BigInteger &b)
Definition: BigInteger.cc:169
X convertToSignedPrimitive() const
Definition: BigInteger.cc:104
int toInt() const
Definition: BigInteger.cc:131
#define DTRT_ALIASED(cond, op)
Definition: BigInteger.cc:161
void operator--()
Definition: BigInteger.cc:390
void multiply(const BigUnsigned &a, const BigUnsigned &b)
Definition: BigUnsigned.cc:300
unsigned int toUnsignedInt() const
Definition: BigInteger.cc:128
Blk getBlock(Index i) const
Definition: BigUnsigned.hh:92
X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a)
Definition: BigInteger.cc:88
static const CmpRes less
Definition: BigInteger.hh:20
void divideWithRemainder(const BigInteger &b, BigInteger &q)
Definition: BigInteger.cc:280
void multiply(const BigInteger &a, const BigInteger &b)
Definition: BigInteger.cc:243
void subtract(const BigInteger &a, const BigInteger &b)
Definition: BigInteger.cc:203
BigUnsigned::Blk Blk
Definition: BigInteger.hh:16