Methods which operate on magnitudes must have these
magnitudes stored in exactly the same format described
for magnitudes in the
Compares two magnitudes, returning
1 if the magnitude pointed to by
Adds the magnitude pointed to by
Adds the
Adds the magnitude pointed to by
Subtracts the magnitude pointed to by
Subtracts the
Subtracts the magnitude pointed to by
Icrements the
Icrements the
Decrements the
Multiplies the
Multplies the two digit magnitude pointed to by
Squares the two digit magnitude pointed to by
Multiplies the
Squares the
Divides the two digit dividend given by
Divides the
The caller is assumed to own the memory pointed
to by
Note:
Returns the bit position (0-31, 0 being least significant) of
the most significant bit which is 1 in
Shifts the bits of the
Shifts the bits of the
Shifts the binary digits of the #include "bmath.hxx"
Who is this Class for?
LInteger
, LMath
, or Monty
classes.
Who is this Class not for?
If this is you, you will lose nothing by skipping this section and
going directly to the section on the
LInteger
class.
Required Representation of Magnitudes
LInteger
class. An exception
to this rule is that lead zeros are ok here, except
where noted otherwise.
See the
magnitude section of the
internal representation section for details.
Basic Algorithms
These two algorithms are not directly implemented, but, nevertheless,
are useful in explaining how the methods in the BMath
class work:
The Ripple Carry Algorithm
Given a starting location start
, rippling a carry
works as given by the following pseudo-code:
set carry flag;
unsigned int* mem=start;
while (carry flag)
{
(*mem)++;
if (overflow)
set carry flag;
else
clear carry flag;
mem--;
}
The Ripple Carry Algorithm
Given a starting location start
, rippling a borrow works
as given by the following pseudo-code:
set borrow flag;
unsigned int* mem=start;
while (borrow flag)
{
(*mem)--;
if (borrow)
set borrow flag;
else
clear borrow flag;
mem--;
}
Public Methods
GreaterThanOrEqualTo
static inline char BMath::GreaterThanOrEqualTo(const
unsigned int* A, const unsigned int* B, const int size)
A
is greater than or
equal to
the magnitude pointed to by B
and 0 otherwise.
A
and B
must have the same number of
digits. This number is specified by size
.
BasicAdd
static inline void BMath::BasicAdd(const unsigned int* A,
const unsigned int* B, unsigned int* C, const int size,
char& carry)
A
to the mangitude
pointed to by B
, and stores the size
least
significant
digits of the result into the memory segment pointed
to by C
. If the addition results in a carry,
carry
is set to 1, otherwise it is set to 0.
A
and B
must have the same number of
digits. This number is specified by size
.
Add
static void BMath::Add(const unsigned int* A, const unsigned int* B,
unsigned int* C, const int sizeOfA, const int sizeOfB, char& carry)
sizeOfB
digit mangitude pointed to by
B
to the sizeOfA
digit mangitude point to
by A
. The magnitude pointed to by A
must have
at least as many digits as the magnitude pointed by B
for this to work. The sizeOfA
least
significant digits of the sum are stored into memory starting at the
location pointed to by C
. If the sum is a
sizeOfA+1
digit number, carry
is set
to 1, otherwise it is set to 0.
RippleAdd
static inline void BMath::RippleAdd(const unsigned int* A,
const unsigned int* B, unsigned int* C, const int size)
A
to the mangitude
pointed to by B
, and stores the size
least significant
digits of the result into the memory segment pointed
to by C
. If the addition results in a carry,
it is rippled as described in the
ripple carry algorithm with a start
point equal to C-1
.
A
and B
must have the same number of
digits. This number is specified by size
.
BasicSubtract
static inline void BMath::BasicSubtract(const unsigned int* A,
const unsigned int* B, unsigned int* C, const int size, char& borrow)
B
from the mangitude
pointed to by B
, and stores size
least
significant
digits of the result into the memory segment pointed
to by C
. If the subtraction requires a borrow,
borrow
is set to 1, otherwise it is set to 0.
A
and B
must have the same number of
digits. This number is specified by size
.
Subtract
static void BMath::Subtract(const unsigned int* A,
const unsigned int* B, unsigned int* C, const int sizeOfA,
const int sizeOfB)
sizeOfA
digit magnitude pointed to by
B
from the sizeOfB
digit mangitude
pointed to by B
, and stores the sizeOfA
least significant digits of the result into memory starting at the
address pointed to by C
. The magnitude poitned to by
A
must be greater than or equal to the magnitude
to by B
and must have at least as many digits for this
method to work.
RippleSubtract
static inline void BMath::RippleSubtract(const unsigned int* A,
const unsigned int* B, unsigned int* C, const int size)
B
from the mangitude
pointed to by A
, and stores size
least
significant
digits of the magnitude of the result into the
memory segment pointed to by C
. If the subtraction requires
in a borrow, it is rippled as descirbed in the
ripple borrow algorithm with a
start point equal to C-1
.
A
and B
must have the same number of
digits. This number is specified by size
.
Increment
static inline void BMath::Increment(unsigned int* linteger,
const int size, char& carry)
size
digit magnitude pointed to by
linteger
by 1. If this increment result in
a carry, carry
is set to 1, otherwise carry
is set to 0.
RippleIncrement
static inline void BMath::RippleIncrement(unsigned int* linteger,
const int size)
size
digit magnitude pointed to by
linteger
by 1. If this increment result in
a carry, it is rippled out via the
ripple carry algorithm
with a start point equal to linteger-1
.
RippleDecrement
static inline void BMath::RippleDecrement(unsigned int* linteger,
const int size)
size
digit magnitude pointed to by
linteger
by 1. If this decrement results in
a borrow, it is rippled out via the
ripple borrow algorithm
with a start point equal to linteger-1
.
BasicMultiply
static inline void BMath::BasicMultiply(const unsigned int* A,
unsigned int B, unsigned int* C, const int sizeA)
sizeA
digit magnitude pointed to by
A
by B
and adds the
sizeA+1
digit result to the
sizeA+1
digit magnitude pointed at by C
,
storing the lower sizeA+1
digits of the result in the
meomry location pointed to by C
.
If this addition results in a carry it is rippled out via the
ripple carry algorithm
with a start point equal to C-1
.
C
must not be equal to A
for this method
to work.
MultDouble
static inline void BMath::MultDouble(unsigned int* productBuf,
const unsigned int* a, const unsigned int* b)
a
by the two digit magnitude pointed to by b
.
The four digit result is stored starting at the memory location
pointed to by productbuf
.
SquareDouble
static inline void BMath::SquareDouble(unsigned int* productBuf,
const unsigned int* a)
a
, and
stores the four digit starting at the memory location
pointed to by productbuf
. This is method is
equivalent to
Mult64(productBuf,a,a)
, except that it is
a bit faster.
Multiply
static void BMath::Multiply(const unsigned int* A, int sizeA,
const unsigned int* B, int sizeB, unsigned int* result)
sizeA
digit magnitude pointed to by
A
by the sizeB
digit magnitude pointed
to by B
and stores the sizeA+sizeB
digit
result starting at the memory location pointed to by result
.
In order for this to work, the memories locations from
result
to result+sizeA+sizeB-1
inclusive must
be zero before this method is called.
Square
static void BMath::Square(const unsigned int* a, const int sizeA,
unsigned int* result)
sizeA
digit magnitude pointed to by
A
and stores the 2*sizeA
result
starting at the memory location pointed to by result
.
In order for this to work, the memories locations from
result
to result+2*sizeA-1
must be zero
before this method is called. This method is equivalent to
Multiply(a,sizeA,a,sizeA,result)
except that it is
a bit faster.
BasicDivide
static inline void BMath::BasicDivide(unsigned int dividendHigh,
unsigned int dividendLow, unsigned int divisor,
unsigned int& quotient, unsigned int& remainder)
dividendHigh*base+dividendLow
by divisor
.
the quotient is stored in quotient
and the
remainder is stored in remainder
. (Shocking, huh? :) )
Be careful that the quotient can fit in an unsigned int
before calling this method, or you'll get a floating exception.
Divide
static void BMath::Divide(const unsigned int* divisor, const int divisorSize,
const unsigned int* dividend, const int dividendSize,
unsigned int*& quotient, unsigned int*& remainder)
dividendSize
digit dividend by
the dividendSize
digit divisor. Upon return,
quotient
points to a dynamically allocated
memory block containing the
dividendSize-divisorSize+1
digit magnitude of the
quotient. remainder
, on the other hand,
points to a dynamically allocated
memory block of dividendSize+1
digits,
the divisorSize
least significant
of which will be magnitude of the
remainder, and the
dividendSize-divisorSize+1
most significant
of which will be zero.
quotient
, and remainder
after this method is called, and, as such, is responsible for freeing it.
Warning:
The interface to this method will almost surely change
in the next version of this library so that the caller will be
responsible for allocating the dynamic memory to store the results
before calling the method.
dividendSize
must be greater than or
equal to divisorSize
for this method to work.
The magnitude pointed to by the divisor may not have lead zeros.
BSR
static inline int BMath::BSR(unsigned int x)
x
.
Normalize
static inline char BMath::Normalize(unsigned int* buf,
int size)
size
digit
magnitude pointed to by buf
the minimum number
of digits left to bring a 1 into the most significant bit.
Zeros are brought in on the right.
The magnitude pointed to by buf
must a least
one bit equal to 1 its most significant digit for this work.
The value returned is equal to the distance of the shift.
ShiftLeft
static inline void BMath::ShiftLeft(unsigned int* buf, int size, char distance)
size
digit magnitude pointed to by buf
left by the number of
positions given by the 5 least significant bits of
distance
.
Zeros are shifted in on the right, while bits shifted out on the left
are lost.
ShiftRight
static inline void BMath::ShiftRight(unsigned int* buf, int size, char distance)
size
digit magnitude pointed to by buf
right by the number of
positions given by the 5 least significant bits of
distance
.
Zeros are shifted in on the left, while bits shifted out on the right
are lost.
Next
Previous
Table of Contents