java.math.MutableBigInteger
is only available from inside the package. It inherits from java.lang.Object
and there is only one subclass (Sign
MutableBigInteger is referenced in the java.math library. If you have a JDK installed check out the contents of src.zip in your jdk directory.
You will see BigInteger uses it:
public BigInteger divide(BigInteger val) { MutableBigInteger q = new MutableBigInteger(), r = new MutableBigInteger(), a = new MutableBigInteger(this.mag), b = new MutableBigInteger(val.mag); a.divide(b, q, r); return new BigInteger(q, this.signum * val.signum); }
MutableBigInteger is an encapsulation of the mathematical algorithms used by BigInteger.
The issue with BigInteger is that it's immutable: in other words, once you have a BigInteger object, you can't change the value of the object itself, you can only replace it with a new object.
Now this is normally a fine thing, since it prevents aliasing and so on (you don't want your "2 + 3" somewhere to suddenly turn into "2 + 5" because a user of that "3" somewhere else in your program changed it into a "5"). However, internally the BigInteger uses an array to hold the components of this value. For a large number, this array can be quite large; a BigInteger representing a bazillion might need an array of, oh, a thousand elements, say.
So what happens when I want to add one to this BigInteger? Well, we create a new BigInteger, which in turn will create a new array internal to it of a thousand elements, copy all of the elements of the old BigInteger's internal array to the new BigInteger's internal array, excepting the last one, and put in a new version of that last element incremented by one. (Or it might need to update the last two.) If you then don't need the old value, it frees up that old BigInteger, which frees up the array.
This is obviously pretty inefficient if you are just getting rid of the old values anyway. So if you have operations like this, you can instead use a MutableBigInteger, which can be incremented by simply changing the last element in the internal array of the existing MutableBigInteger. This is far faster! However, it does destroy the old value, which can be problematic, as I pointed out above. If someone gives you the int "3", you can expect that to stay the same. If someone gives you a MutableBigInteger, don't expect it to be the same number later on!
/**
* A class used to represent multiprecision integers that makes efficient
* use of allocated space by allowing a number to occupy only part of
* an array so that the arrays do not have to be reallocated as often.
* When performing an operation with many iterations the array used to
* hold a number is only reallocated when necessary and does not have to
* be the same size as the number it represents. A mutable number allows
* calculations to occur on the same number without having to create
* a new number for every step of the calculation as occurs with
* BigIntegers.
*
* @see BigInteger
* @version 1.12, 12/19/03
* @author Michael McCloskey
* @since 1.3
*/
Source.
I'd guess MutableBigInteger is used internally for BigInteger heavy calculations that are slowed down by frequent reallocations. I'm not sure why its not exported as part of java.math. Perhaps some distaste for mutable value classes?
To clarify "mutable":
Standard BigInteger has one value for its entire lifetime, given two BigInteger references "a" & "b", "a+b" will always yield a new BigInteger with the same value. Let's say that value is 4.
With MutableBigInteger, "a+b" could yield 4 initially, yet yield 8, 16, 32, or any other number at some point in the future due to OTHER code changing the values (aka. mutating) of the objects referenced by "a" & "b". Accordingly, most (perhaps all) of the value types (Character, Short, Long, Integer, BigInteger, BigDecimal, Float, Double, even String) in Java are immutable.