2011-06-12 25 views
6

Actualmente estoy implementando una ecuación (2^A)[X + Y*(2^B)] en una de mis aplicaciones.Desbordamiento de la variable de 32 bits

El problema es con el desbordamiento del valor de 32 bits y no puedo usar el tipo de datos de 64 bits.

Supongamos que cuando B = 3 y Y = 805306367, desborda valor de 32 bits, pero cuando X = -2147483648, el resultado vuelve al rango de 32 bits.
Así que quiero almacenar el resultado de (Y*2^B). ¿Alguien puede sugerir alguna solución para esto .... A y B están teniendo valor de -15 a 15 y X, Y pueden tener valores de 2147483647..-2147483648.
La salida puede ir desde 0...4294967295.

+2

Si A = B = 15 y X = Y = 2147483647, entonces el resultado es mucho mayor que 4294967295. ¿Existen otras restricciones que vinculen la salida en el rango 0 ... 4294967295? – Andrei

+0

En tu ecuación, ¿'^' xor, o power? ¿Qué representan los corchetes? –

Respuesta

6

Si el número es demasiado grande para una variable de 32 bits, entonces puede utilizar más bits (ya sea almacenando en una variable más grande o utilizando múltiples variables) o abandona la precisión y la almacena en un flotador. Como Y puede ser MAX_INT, por definición no puede multiplicarlo por un número mayor que 1 y todavía puede caber en un int de 32 bits.

1

Utilizaría el bucle, en lugar de la multiplicación, en este caso. Algo como esto:

int newX = X; 
int poweredB = (1 << B); // 2^B 
for(int i = 0; i < poweredB ; ++i) 
{ 
    newX += Y; // or change X directly, if you will not need it later. 
} 
int result = (1 << A) * newX; 

Pero nota: esto funcionará solamente para algunas situaciones - sólo si usted tiene la garantía de , que este resultado no se derrame. En su caso, cuando Y es grande positivo y X es gran número negativo ("grande" - argh, esto es demasiado subjetivo), esto definitivamente funcionará. Pero si X es positivo grande e Y es positivo grande, habrá desbordamiento nuevamente. Y no solo en este caso, sino con muchos otros.

+0

+1 para mostrar que no se necesita multiplicación, solo cambios. – Codo

1

Basándose en los valores para A y B en la asignación supongo que la solución esperada implicaría esto:

  • la siguiente se realiza mejor sin signo de modo almacenar las señales para X e Y y operar en su absoluta valor

  • tienda X e y en dos variables cada uno, uno que sostienen los altos 16 bits la otra sosteniendo los bajos bits de algo como
    int hiy = y & 0xFFFF0000;

    int loY = Y & 0x0000FFFF;

  • desplazar la piezas de alta derecha de modo que todas las variables tienen los bits altos 0

  • Y * (2^B) es en realidad un cambio de Y a la izquierda por B bits.Es equivalente a desplazar las partes alta y baja por los bits B y, desde que ha desplazado la parte alta, ambas operaciones se encajan dentro de su entero de 32 bits

  • Proceso X Del mismo modo, en las partes altas y bajas

  • un seguimiento de los signos de X e y calcular X + y * (2^B) para las partes de alta y baja

  • de nuevo desplazar tanto los resultados de alta y baja por una bits de

  • Inscripción en el partes altas y bajas en el resultado final

1

Si no puede utilizar 64 bits debido a su local de C no es compatible con ellos en lugar de alguna otra razón imperiosa, es posible considerar El GNU múltiple de precisión aritmética Biblioteca en http://gmplib.org/

Cuestiones relacionadas