2009-05-21 26 views

Respuesta

3
/** 
* 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.

Supongo que MutableBigInteger se usa internamente para cálculos pesados ​​de BigInteger que se ralentizan por reasignaciones frecuentes. No estoy seguro de por qué no se exporta como parte de java.math. Tal vez un disgusto por las clases de valores mutables?

Para aclarar "mutable":
Standard BigInteger tiene un valor para toda su vida útil, dado dos referencias BigInteger "a" & "b", "a + b" siempre dará un nuevo BigInteger con el mismo valor. Digamos que el valor es 4.

Con MutableBigInteger, "a + b" podría producir 4 inicialmente, pero producir 8, 16, 32 o cualquier otro número en algún momento en el futuro debido a que OTRO código cambia los valores (aka. mutating) de los objetos a los que hace referencia "a" & "b". En consecuencia, la mayoría (quizás todos) de los tipos de valor (Carácter, Corto, Largo, Entero, BigInteger, BigDecimal, Float, Double, incluso String) en Java son inmutables.

+0

Gracias por responder. Quizás las preguntas deberían ser: "¿Por qué no es una clase pública?". Creo que esa clase podría ser muy útil, especialmente para las variables de ciclo. –

+0

He expandido mi respuesta un poco en consecuencia. Básicamente, probablemente no sea mutable porque otros tipos de valores tampoco son mutables. Es una convención, de verdad. –

4

El problema con BigInteger es que es inmutable: en otras palabras, una vez que tiene un objeto BigInteger, no puede cambiar el valor del objeto en sí, solo puede reemplazarlo con un objeto nuevo.

Ahora esto normalmente es algo bueno, ya que evita el aliasing y demás (no desea que su "2 + 3" en algún lugar se convierta repentinamente en "2 + 5" porque un usuario de ese "3" en alguna parte si no en su programa, lo cambió a un "5"). Sin embargo, internamente, BigInteger usa una matriz para contener los componentes de este valor. Para un gran número, esta matriz puede ser bastante grande; un BigInteger que representa un bazillion podría necesitar una matriz de, oh, mil elementos, por ejemplo.

¿Qué sucede cuando quiero agregar uno a este BigInteger? Bueno, creamos un nuevo BigInteger, que a su vez creará una nueva matriz interna de mil elementos, copiará todos los elementos de la matriz interna de BigInteger a la nueva matriz interna de BigInteger, excepto la última, y ​​colocará una nueva versión de ese último elemento incrementada en uno. (O podría necesitar actualizar los dos últimos.) Si no necesita el valor anterior, libera ese BigInteger anterior, lo que libera la matriz.

Esto es obviamente bastante ineficiente si solo se está deshaciendo de los valores anteriores de todos modos. Por lo tanto, si tiene operaciones como esta, puede usar MutableBigInteger, que puede incrementarse simplemente cambiando el último elemento en la matriz interna del MutableBigInteger existente. ¡Esto es mucho más rápido! Sin embargo, destruye el valor anterior, lo que puede ser problemático, como señalé anteriormente. Si alguien te da el int "3", puedes esperar que permanezca igual. Si alguien te da un MutableBigInteger, ¡no esperes que sea el mismo número más tarde!

+0

Gracias por responder. Usted describió la forma en que la clase funciona muy bien. Pero te perdiste una cosa: la clase no es pública (declarada sin o con el modificador predeterminado). Por lo tanto, no está disponible desde fuera del paquete java.math. –

+0

@ c0d3x y Curt, ciertamente no hay nada de malo en crear una bandera de constructor inmutable en una clase que de otro modo sería inmutable, o viceversa. Eso sin duda protegería su "3". Estoy más que un poco molesto porque no hay LongLong mutable y similar para las variantes BigInteger. Siento que este negocio inmutable es un poco torpe de pedantería y viola la ley de la menor sorpresa, tanto al usarlo como al leer el código que lo usa. En serio, ¿alguno de ustedes ha visto una página? Es simplemente asqueroso. –

+0

He visto decenas de miles de líneas de código casi inmutables. Se llama Haskell, y es maravilloso. :-) Honestamente, hacer que la mayoría de sus datos sean inmutables casi siempre facilita la programación. Sin embargo, a menudo es cierto que, en sistemas que dependen en gran medida de la mutabilidad en todo el sistema, tratar de introducir la inmutabilidad puede ser incómodo. Eso no es realmente un problema con el concepto; es un problema porque no se aplica bien. –

1

MutableBigInteger se hace referencia en la biblioteca java.math. Si tiene un JDK instalado, revise los contenidos de src.zip en su directorio jdk.

Verá BigInteger lo utiliza:

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 es una encapsulación de los algoritmos matemáticos usados ​​por BigInteger.

Cuestiones relacionadas