Hi.

(posted to both newsgroups since I was not sure of which would be

appropriate for this question or how specific to the given language it

is. If one of them is inappropriate, just don't send replies to it.)

I'm making a bignum package for use in a program I've got (this is

something different from the pi program you may have heard about). The

package is going to support manipulating long floating point numbers.

The way I have this set up right now is that there is a "raw" unsigned

integer package, from which the floating point package is built on top

of. The questions I have are about coding that lower-level package.

See, I have a routine here that adds up two unsigned integers, but it

also must be able to add so many digits of one starting at one point

in it's data, to so many digits of the other starting at a different

point in it's data, and finally store so many digits of the result at

yet another point in the data buffer holding the result.

This is what I've got (it's in C++, not C, by the way). The problem is

it just doesn't seem like a "neat", or "nice" piece of code. Anyone

know of a better way to approach this?:

/* Add two RawInts.

* Parameters:

* a: First RawInt

* b: Second RawInt

* rOrigin: offset of digit in this to store result at

* rLength: length of region in this to store result in

* aOrigin: offset of digit in a to start addition at

* aLength: length of region in a to add

* bOrigin: offset of digit in b to start addition at

* bLength: length of region in b to add

*

* Returns: carry.

*

* Operation: *this = a + b.

*

* Use ?Origin = 0 and ?Length = -1 for a simple integer addition

* operation.

*/

DIGIT RawInt::rawAdd(const RawInt &a,

const RawInt &b,

int rOrigin, int rLength,

int aOrigin, int aLength,

int bOrigin, int bLength)

{

int i;

DIGIT tmp, carry = 0;

int rlen2, alen2, blen2;

std::vector<DIGIT>::iterator di, de;

std::vector<DIGIT>::const_iterator ai, ae;

std::vector<DIGIT>::const_iterator bi, be;

/* Make sure we don't exceed the boundaries

* of the digit arrays.

*/

if(rLength != -1)

{

rlen2 = rLength;

if(rlen2 (length - rOrigin))

rlen2 = (length - rOrigin);

} else {

rlen2 = (length - rOrigin);

}

if(aLength != -1)

{

alen2 = aLength;

if(alen2 (a.length - aOrigin))

alen2 = (a.length - aOrigin);

} else {

alen2 = (a.length - aOrigin);

}

if(bLength != -1)

{

blen2 = bLength;

if(blen2 (b.length - bOrigin))

blen2 = (b.length - bOrigin);

} else {

blen2 = (b.length - bOrigin);

}

if(rOrigin+alen2 >= length)

alen2 = length-rOrigin;

if(rOrigin+blen2 >= length)

blen2 = length-rOrigin;

if(alen2 rlen2) alen2 = rlen2;

if(blen2 rlen2) blen2 = rlen2;

if(alen2 < 0) alen2 = 0;

if(blen2 < 0) blen2 = 0;

/* Set up the iterators */

di = digits.begin()+rOrigin; de = digits.end();

ai = a.digits.begin()+aOrigin; ae = a.digits.end();

bi = b.digits.begin()+bOrigin; be = b.digits.end();

/* Now do the addition */

if(alen2 >= blen2)

{

/* Case 1: a is at least as long as b */

/* Add up a's and b's digits */

for(i=0;i<blen2;i++,++di,++ai,++bi)

{

tmp = *ai + *bi + carry;

if(carry) carry = (tmp <= *bi) ? 1 : 0;

else carry = (tmp < *bi) ? 1 : 0;

*di = tmp;

}

/* Now tackle the part of a that is longer than b */

for(i=blen2;i<alen2;i++,++di,++ai)

{

tmp = *ai + carry;

if(carry)

carry = (tmp == 0) ? 1 : 0;

*di = tmp;

}

/* Zeroize the rest of this. */

for(i=alen2;i<rlen2;i++,++di)

{

*di = carry;

carry = 0;

}

} else {

/* Case 2: b is longer than a */

/* Add up a's and b's digits */

for(i=0;i<alen2;i++,++di,++ai,++bi)

{

tmp = *ai + *bi + carry;

if(carry) carry = (tmp <= *bi) ? 1 : 0;

else carry = (tmp < *bi) ? 1 : 0;

*di = tmp;

}

/* Now tackle the part of b that is longer than a */

for(i=alen2;i<blen2;i++,++di,++bi)

{

tmp = *bi + carry;

if(carry) carry = (tmp <= *bi) ? 1 : 0;

else carry = (tmp < *bi) ? 1 : 0;

*di = tmp;

}

/* Zeroize the rest of this. */

for(i=blen2;i<rlen2;i++,++di)

{

*di = carry;

carry = 0;

}

}

/* Done! Return any leftover carry. */

return(carry);

}