LSST Applications g0f08755f38+9c285cab97,g1635faa6d4+13f3999e92,g1653933729+a8ce1bb630,g1a0ca8cf93+bf6eb00ceb,g28da252d5a+0829b12dee,g29321ee8c0+5700dc9eac,g2bbee38e9b+9634bc57db,g2bc492864f+9634bc57db,g2cdde0e794+c2c89b37c4,g3156d2b45e+41e33cbcdc,g347aa1857d+9634bc57db,g35bb328faa+a8ce1bb630,g3a166c0a6a+9634bc57db,g3e281a1b8c+9f2c4e2fc3,g414038480c+077ccc18e7,g41af890bb2+fde0dd39b6,g5fbc88fb19+17cd334064,g781aacb6e4+a8ce1bb630,g80478fca09+55a9465950,g82479be7b0+d730eedb7d,g858d7b2824+9c285cab97,g9125e01d80+a8ce1bb630,g9726552aa6+10f999ec6a,ga5288a1d22+2a84bb7594,gacf8899fa4+c69c5206e8,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+9634bc57db,gcf0d15dbbd+4b7d09cae4,gda3e153d99+9c285cab97,gda6a2b7d83+4b7d09cae4,gdaeeff99f8+1711a396fd,ge2409df99d+5e831397f4,ge79ae78c31+9634bc57db,gf0baf85859+147a0692ba,gf3967379c6+41c94011de,gf3fb38a9a8+8f07a9901b,gfb92a5be7c+9c285cab97,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
Public Member Functions | List of all members
lsst::sphgeom::BigInteger Class Reference

BigInteger is an arbitrary precision signed integer class. More...

#include <BigInteger.h>

Public Member Functions

 BigInteger (std::uint32_t *digits, unsigned capacity)
 This constructor creates a zero-valued integer with the given digit array.
 
BigIntegeroperator= (BigInteger const &b)
 
int getSign () const
 getSign returns -1, 0 or 1 if this integer is negative, zero or positive.
 
unsigned getSize () const
 getSize returns the number of digits in the value of this integer.
 
unsigned getCapacity () const
 getCapacity returns the number of digits in the underlying digit array.
 
std::uint32_t const * getDigits () const
 getDigits returns the underlying digit array.
 
void setToZero ()
 setToZero sets this integer to zero.
 
void setTo (std::int64_t x)
 setTo sets this integer to the given signed 64 bit integer value.
 
void setTo (std::uint64_t x)
 setTo sets this integer to the given unsigned 64 bit integer value.
 
void negate ()
 negate multiplies this integer by -1.
 
BigIntegeradd (BigInteger const &b)
 add adds b to this integer.
 
BigIntegersubtract (BigInteger const &b)
 subtract subtracts b from this integer.
 
BigIntegermultiplyPow2 (unsigned n)
 multiplyPow2 multiplies this integer by 2ⁿ.
 
BigIntegermultiply (BigInteger const &b)
 multiply multiplies this integer by b.
 

Detailed Description

BigInteger is an arbitrary precision signed integer class.

It is intended to be used in applications which need relatively small integers, and only supports addition, subtraction and multiplication.

Internally, a BigInteger consists of a sign and an unsigned magnitude. The magnitude is represented by an array of 32 bit digits, stored from least to most significant. All non-zero integers have at least one digit, the most significant of which is non-zero. Zero is defined to have no digits.

Definition at line 51 of file BigInteger.h.

Constructor & Destructor Documentation

◆ BigInteger()

lsst::sphgeom::BigInteger::BigInteger ( std::uint32_t * digits,
unsigned capacity )
inline

This constructor creates a zero-valued integer with the given digit array.

Definition at line 55 of file BigInteger.h.

55 :
56 _digits(digits),
57 _capacity(capacity),
58 _size(0),
59 _sign(0)
60 {}

Member Function Documentation

◆ add()

BigInteger & lsst::sphgeom::BigInteger::add ( BigInteger const & b)

add adds b to this integer.

Definition at line 163 of file BigInteger.cc.

163 {
164 if (b._sign == 0) {
165 return *this;
166 }
167 if (_sign == 0) {
168 *this = b;
169 return *this;
170 }
171 if (this == &b) {
172 return multiplyPow2(1);
173 }
174 // When adding two magnitudes, the maximum number of bits in the result is
175 // one greater than the number of bits B in the larger input. When
176 // subtracting them, the maximum result size is B.
177 _checkCapacity(std::max(_size, b._size) + 1);
178 if (_sign == b._sign) {
179 // If the signs of both integers match, add their magnitudes.
180 _size = _add(_digits, _digits, b._digits, _size, b._size);
181 return *this;
182 }
183 // Otherwise, subtract the smaller magnitude from the larger. The sign of
184 // the result is the sign of the input with the larger magnitude.
185 if (_size > b._size) {
186 _size = _sub(_digits, _digits, b._digits, _size, b._size);
187 } else if (_size < b._size) {
188 _size = _sub(_digits, b._digits, _digits, b._size, _size);
189 _sign = b._sign;
190 } else {
191 // Both magnitudes have the same number of digits. Compare and discard
192 // leading common digits until we find a digit position where the
193 // magnitudes differ, or we determine that they are identical.
194 int i = _size;
195 for (; i > 0 && _digits[i - 1] == b._digits[i - 1]; --i) {}
196 if (i == 0) {
197 setToZero();
198 } else if (_digits[i - 1] > b._digits[i - 1]) {
199 _size = _sub(_digits, _digits, b._digits, i, i);
200 } else {
201 _size = _sub(_digits, b._digits, _digits, i, i);
202 _sign = b._sign;
203 }
204 }
205 return *this;
206}
table::Key< int > b
BigInteger & multiplyPow2(unsigned n)
multiplyPow2 multiplies this integer by 2ⁿ.
void setToZero()
setToZero sets this integer to zero.
Definition BigInteger.h:87
T max(T... args)

◆ getCapacity()

unsigned lsst::sphgeom::BigInteger::getCapacity ( ) const
inline

getCapacity returns the number of digits in the underlying digit array.

Definition at line 81 of file BigInteger.h.

81{ return _capacity; }

◆ getDigits()

std::uint32_t const * lsst::sphgeom::BigInteger::getDigits ( ) const
inline

getDigits returns the underlying digit array.

Definition at line 84 of file BigInteger.h.

84{ return _digits; }

◆ getSign()

int lsst::sphgeom::BigInteger::getSign ( ) const
inline

getSign returns -1, 0 or 1 if this integer is negative, zero or positive.

Definition at line 74 of file BigInteger.h.

74{ return _sign; }

◆ getSize()

unsigned lsst::sphgeom::BigInteger::getSize ( ) const
inline

getSize returns the number of digits in the value of this integer.

Definition at line 77 of file BigInteger.h.

77{ return _size; }

◆ multiply()

BigInteger & lsst::sphgeom::BigInteger::multiply ( BigInteger const & b)

multiply multiplies this integer by b.

Definition at line 256 of file BigInteger.cc.

256 {
257 _sign *= b._sign;
258 if (_sign == 0) {
259 _size = 0;
260 return *this;
261 }
262 _checkCapacity(_size + b._size);
263 if (_size >= b._size) {
264 _size = _mul(_digits, _digits, b._digits, _size, b._size);
265 } else {
266 _size = _mul(_digits, b._digits, _digits, b._size, _size);
267 }
268 return *this;
269}

◆ multiplyPow2()

BigInteger & lsst::sphgeom::BigInteger::multiplyPow2 ( unsigned n)

multiplyPow2 multiplies this integer by 2ⁿ.

Definition at line 221 of file BigInteger.cc.

221 {
222 if (_sign == 0 || n == 0) {
223 return *this;
224 }
225 // Decompose n into (s, z), where s is a shift by less than 32 bits, and
226 // z is the number of trailing zero digits introduced by the shift.
227 unsigned const z = (n >> 5);
228 unsigned const s = (n & 0x1f);
229 unsigned const size = _size + z;
230 _checkCapacity(size + 1);
231 if (s == 0) {
232 // Right-shifting an unsigned 32 bit integer by 32 bits is undefined
233 // behavior. Avoid that using this special case code.
234 for (unsigned i = _size; i != 0; --i) {
235 _digits[i + z - 1] = _digits[i - 1];
236 }
237 for (unsigned i = z; i != 0; --i) {
238 _digits[i - 1] = 0;
239 }
240 _size = size;
241 } else {
242 std::uint32_t low, high = 0;
243 for (unsigned i = _size; i != 0; --i, high = low) {
244 low = _digits[i - 1];
245 _digits[i + z] = (high << s) | (low >> (32 - s));
246 }
247 _digits[z] = high << s;
248 for (unsigned i = z; i != 0; --i) {
249 _digits[i] = 0;
250 }
251 _size = (_digits[size] == 0) ? size: size + 1;
252 }
253 return *this;
254}
double z
Definition Match.cc:44

◆ negate()

void lsst::sphgeom::BigInteger::negate ( )
inline

negate multiplies this integer by -1.

Definition at line 109 of file BigInteger.h.

109{ _sign = -_sign; }

◆ operator=()

BigInteger & lsst::sphgeom::BigInteger::operator= ( BigInteger const & b)
inline

Definition at line 62 of file BigInteger.h.

62 {
63 if (this != &b) {
64 _checkCapacity(b._size);
65 _sign = b._sign;
66 _size = b._size;
67 std::memcpy(_digits, b._digits, sizeof(std::uint32_t) * b._size);
68 }
69 return *this;
70 }
T memcpy(T... args)

◆ setTo() [1/2]

void lsst::sphgeom::BigInteger::setTo ( std::int64_t x)
inline

setTo sets this integer to the given signed 64 bit integer value.

Definition at line 90 of file BigInteger.h.

90 {
91 if (x < 0) {
92 setTo(static_cast<std::uint64_t>(-x));
93 _sign = -1;
94 } else {
95 setTo(static_cast<std::uint64_t>(x));
96 }
97 }
void setTo(std::int64_t x)
setTo sets this integer to the given signed 64 bit integer value.
Definition BigInteger.h:90

◆ setTo() [2/2]

void lsst::sphgeom::BigInteger::setTo ( std::uint64_t x)
inline

setTo sets this integer to the given unsigned 64 bit integer value.

Definition at line 100 of file BigInteger.h.

100 {
101 _checkCapacity(2);
102 _digits[0] = static_cast<std::uint32_t>(x);
103 _digits[1] = static_cast<std::uint32_t>(x >> 32);
104 _size = (_digits[1] == 0) ? (_digits[0] != 0) : 2;
105 _sign = (_size != 0);
106 }

◆ setToZero()

void lsst::sphgeom::BigInteger::setToZero ( )
inline

setToZero sets this integer to zero.

Definition at line 87 of file BigInteger.h.

87{ _sign = 0; _size = 0; }

◆ subtract()

BigInteger & lsst::sphgeom::BigInteger::subtract ( BigInteger const & b)

subtract subtracts b from this integer.

Definition at line 208 of file BigInteger.cc.

208 {
209 if (this != &b) {
210 // Avoid code duplication by computing a - b = -(-a + b).
211 // This only works if a and b are distinct.
212 negate();
213 add(b);
214 negate();
215 } else {
216 setToZero();
217 }
218 return *this;
219}
void negate()
negate multiplies this integer by -1.
Definition BigInteger.h:109
BigInteger & add(BigInteger const &b)
add adds b to this integer.

The documentation for this class was generated from the following files: