Help with BigInteger addition

B

Bert Sierra

OK --

Most of the Java API makes sense to me, but there are aspects of the
java.math.BigInteger package that have me stumped. Any help would be
appreciated.

In one piece of code, I was trying to add two BigIntegers, as follows:
BigInteger a = ...something...
BigInteger b = ...something...
BigInteger c = a.add(b);

What I quickly discovered was that in some cases the result was returned
by destroying the value in a, and in other cases by destroying the value
in b. I couldn't see a pattern that would explain this behaviour, and
unfortunately in the code I was working with I needed consistent
behaviour.

The Sun API doc was fairly vague, claiming only that add(val) would
return a BigInteger whose value is (this + val) [see
<http://java.sun.com/j2se/1.4.2/docs/api/java/math/BigInteger.html#add(ja
va.math.BigInteger)>]. It wouldn't explain any side effects of the
addition on the original arguments -- whether the addition would recycle
the objects used, or would result in a new BigInteger being created.

In the end, I had to augment my code to make copies of the original
BigIntegers prior to the addition, as shown below. I don't like the
fact that I'm creating additional objects, but it's necessary because I
can't figure out how add() [and subtract() and multiply()] operates:

BigInteger a = ...something...
BigInteger b = ...something...
BigInteger acopy = new BigInteger( a.toByteArray() );
BigInteger bcopy = new BigInteger( b.toByteArray() );
BigInteger c = acopy.add(bcopy);

Seems like an awful lot of work to safely add two integers!!

TIA for any advice....
 
M

Michael Borgwardt

Bert said:
In one piece of code, I was trying to add two BigIntegers, as follows:
BigInteger a = ...something...
BigInteger b = ...something...
BigInteger c = a.add(b);

What I quickly discovered was that in some cases the result was returned
by destroying the value in a, and in other cases by destroying the value
in b.

That's impossible unless your Java implementation is very broken.
More likely, your code is broken.
The Sun API doc was fairly vague, claiming only that add(val) would
return a BigInteger whose value is (this + val) [see
<http://java.sun.com/j2se/1.4.2/docs/api/java/math/BigInteger.html#add(ja
va.math.BigInteger)>]. It wouldn't explain any side effects of the
addition on the original arguments -- whether the addition would recycle
the objects used, or would result in a new BigInteger being created.

There is no vagueness. The very first word of the API doc for BigInteger
is "Immutable". A BigInteger, once created, will not change, ever.
So there *are no* side effects. There are, however, cases where the
object returned will be one of the two objects that were added (if the
other one is 0).

Try to write a program as simple as possible that demonstrates this
"destruction" of the arguments to the addition operation. You'll
either find what part of your code is broken, find that you can't
reproduce this behaviour outside the rest of your code (where there's
something broken), or we'll be able to point out what your doing wrong
immediately after seeing this program.

Of course, all of this assumes that it is in fact not your Java
implementation that's broken, but Sun's releases are very unlikely
to contain such an obvious violation of the API contract.
 
R

Rogan Dawes

Bert said:
OK --

Most of the Java API makes sense to me, but there are aspects of the
java.math.BigInteger package that have me stumped. Any help would be
appreciated.

In one piece of code, I was trying to add two BigIntegers, as follows:
BigInteger a = ...something...
BigInteger b = ...something...
BigInteger c = a.add(b);

What I quickly discovered was that in some cases the result was returned
by destroying the value in a, and in other cases by destroying the value
in b. I couldn't see a pattern that would explain this behaviour, and
unfortunately in the code I was working with I needed consistent
behaviour.

That shouldn't happen. BigIntegers are immutable - that is, it cannot be
changed, just like normal Integer, or the other Number classes.
The Sun API doc was fairly vague, claiming only that add(val) would
return a BigInteger whose value is (this + val) [see
<http://java.sun.com/j2se/1.4.2/docs/api/java/math/BigInteger.html#add(ja
va.math.BigInteger)>]. It wouldn't explain any side effects of the
addition on the original arguments -- whether the addition would recycle
the objects used, or would result in a new BigInteger being created.

Yes, the return value of the various operations is a new BigInteger
instance, that holds the result of the operation that was performed. The
arguments (a and b) are not modified.
In the end, I had to augment my code to make copies of the original
BigIntegers prior to the addition, as shown below. I don't like the
fact that I'm creating additional objects, but it's necessary because I
can't figure out how add() [and subtract() and multiply()] operates:

BigInteger a = ...something...
BigInteger b = ...something...
BigInteger acopy = new BigInteger( a.toByteArray() );
BigInteger bcopy = new BigInteger( b.toByteArray() );
BigInteger c = acopy.add(bcopy);

Seems like an awful lot of work to safely add two integers!!
Seems to me like you are doing something wrong.
TIA for any advice....

Check your code more carefully. You'll surely find your mistake.

Rogan
 
P

Paul Lutus

Bert said:
OK --

Most of the Java API makes sense to me, but there are aspects of the
java.math.BigInteger package that have me stumped. Any help would be
appreciated.

In one piece of code, I was trying to add two BigIntegers, as follows:
BigInteger a = ...something...
BigInteger b = ...something...
BigInteger c = a.add(b);

What I quickly discovered was that in some cases the result was returned
by destroying the value in a, and in other cases by destroying the value
in b.

Post examples of each case. Post short, compilable, working examples. Show
the behavior you are saying exists.
 
B

Bert Sierra

Michael Borgwardt said:
That's impossible unless your Java implementation is very broken.
More likely, your code is broken.

I took a closer look at my code, and you folks were right -- there was a
problem in my code where I was incorrectly swapping references to two
BigIntegers. To be sure, I wrote a simple piece of test code that spits
out a Fibonacci sequence (below). In the first iteration of the loop, c
is assigned the reference to b, since b and c are both equal to 1. In
the second and subsequent iterations of the loop, c is assigned a
references to new BigInteger objects: 2, 3, 5, 8, 13, and so on ad
infinitum...


import java.math.BigInteger;

public class FibonacciSequence {
public static void main (String args[]) {
BigInteger a = BigInteger.ZERO;
BigInteger b = BigInteger.ONE;

while (true) {
System.out.println(b);
BigInteger c = a.add(b);
a = b;
b = c;
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top