Pregunta

long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5);

long long int out = A + B*D;

printf("%lld",out);

Esto da el resultado: -2147483648

No puedo entender por qué (debería ser un resultado positivo). ¿Alguien puede ayudar?

¿Fue útil?

Solución

Supongo que el compilador necesita redondear el resultado de " A + B * D " primero a un entero, porque está almacenando el resultado dentro de un campo int. Entonces, básicamente, estás teniendo un conflicto de tipo de datos.

Tanto A como B siguen siendo números válidos para un int largo, que tiene 8 bytes de longitud. Incluso podría multiplicarlos por 1.000 y seguir teniendo valores int largos largos largos válidos. En algunos otros idiomas también se conoce como int64.

Un doble, sin embargo, también es de 64 bits, pero parte de ellos se usa como exponente. Cuando multiplica un doble con un int64, el resultado sería otro doble. Agregarle otro int64 todavía lo mantiene doble. Luego está asignando el resultado a un int64 nuevamente sin usar un método de redondeo específico. No me sorprendería si el compilador usaría una función de redondeo de 4 bits para esto. ¡Incluso estoy sorprendido de que el compilador no vomite y rompa esa declaración!

De todos modos, cuando use números grandes como estos, debe tener mucho cuidado al mezclar diferentes tipos.

Otros consejos

tal vez tenga que especificar esas constantes como " long long " literales? p.ej. 3289168178315264LL

¿Qué compilador / sistema operativo está utilizando? Ejecuté su código usando Visual C ++ 2008 Express Edition en Windows XP y FUNCIONA - respuesta: 6578336356630528 (este es un número de 53 bits, por lo que solo cabe dentro de un doble).

También probé dos variaciones para ver si importaba el orden de las operaciones:

long long int out = A; fuera + = B * D;

long long int out = B * D; out + = A;

¡Ambos funcionan también!

Curioso.

Su respuesta (tiene que verificar) se calcula con éxito, sin embargo, causa un desbordamiento en el bit de signo, lo que hace que la respuesta sea negativa. Solución: haga que todas sus variables no estén firmadas.

Por qué:

Los números se almacenan como series de bits en la memoria de su computadora. El primer bit de dicha serie, cuando se establece, significa que su número es negativo. Entonces el cálculo funciona, pero se desborda en el bit de signo.

Recomendación:

Si está trabajando con números tan grandes, le recomiendo que obtenga una biblioteca de aritmética de precisión múltiple. 'T te ahorrará mucho tiempo y problemas.

El parámetro para sqrt debe ser doble .

#include <math.h>
double sqrt( double num );

Y también debemos explotar el resultado de B * D a largo largo.

    long long int A = 3289168178315264;
    long long int B = 1470960727228416;
    double D = sqrt(5.0);
    printf("%f\n",D);
    long long int out = A + (long long) (B * D);
    printf("%lld",out);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top