¿Por qué obtengo resultados diferentes para una ecuación en C ++?

¡Bienvenido al maravilloso mundo de las conversiones aritméticas habituales [1]!

Larga historia corta en lenguajes familiares C, las constantes tienen el tipo [2] y cuando se usan en operaciones aritméticas pasan por un conjunto estándar de promociones cuando se usan.

El literal “1” tiene el tipo int, cuyo tamaño puede variar de una plataforma a otra. ayb son ambos enteros, por lo que la expresión se evaluará en el tipo de clasificación más baja que se ajuste a ambos operandos. 1 / a [i] [i] = int. Terminas perdiendo la parte fraccional del resultado de la división antes de multiplicar por el resultado de b [i] – S.

1.0 es flotante, por lo que un [i] [i] es promovido a flotante antes de que se realice la división, y puedes mantener la parte fraccional de la división.

Hay todo un conjunto de ejemplos divertidos relacionados con esto.

int a = -10;
sin int int b = 2;
int c = a / b; // c = 5
int d = a / ((int) b); // c = -5

int16_t a = -10;
uint16_t b = 2;
int16_t c = a / b; // si int es 2 bytes, obtendrás 5. si int es más, obtendrás -5. Depende de tu compilador!

int a = -5;
unsigned int = 10;
si (a <b) {
printf (“Puedes pensar que vas aquí”);
} más {
printf {“Pero terminas aquí en su lugar”};
}

Notas al pie

[1] http://www.open-std.org/jtc1/sc2…

[2] C Constantes y literales

Dios, espero que en realidad no uses nombres de variables de una letra en tu código, sino que los hayas acortado a caracteres individuales para evitar revelar secretos de la compañía.

No puedo decir con certeza, pero supongo que es porque los números de coma flotante (doble, flotante, etc.) son aproximaciones, no valores exactos. Muchos números que no se repiten en la base decimal se convierten en números que se repiten en la representación binaria de coma flotante de dobles y flotantes. Por lo tanto, en

int oneAsInteger = 1;
doble oneAsDouble = 1.0;
double oneAsDoubleCastFromInteger = (doble) oneAsInteger;

no hay garantía de que

oneAsDouble == oneAsDoubleCastFromInteger

.

Cuando se trabaja con operaciones de punto flotante binario, comparar dos valores de punto flotante para la igualdad a menudo conduce a problemas serios: hay una garantía de igualdad aproximada , no igualdad exacta .

Por lo general, para probar si dos puntos flotantes son iguales, defina un épsilon que represente la menor diferencia aceptable entre dos números. Puede escribir un método como este y usar un épsilon de, por ejemplo, 0.0000001:

#include

bool are_equal (doble first_comparand, doble second_comparand, double epsilon)
{
diferencia doble = std :: abs (first_comparand – second_comparand);
diferencia de retorno <= std :: abs (epsilon);
}

C ++ no tiene ecuaciones. Tiene tareas. Debe leer un libro completo sobre programación en C ++.

También necesita leer sobre números de coma flotante. Comience con lo que todo programador debe saber sobre la aritmética de punto flotante

Si a[i][i] es int, …

  • 1.0/a[i][i] , convierte a a double y realiza una división entre dobles, mientras que …
  • 1/a[i][i] realiza una división entre enteros (truncando la parte fraccionaria del resultado y dando un entero).

El resultado se convierte en doble (si no es así) para multiplicarse por un double ya que como tal es el resultado de (…) ser S un double .

En el segundo caso hay un truncamiento que en el primero no existe.


PD: Nunca uses la palabra ” ecuación ” cuando hables de expresión con un operador = : es ” asignación “.

La ecuación es una bestia completamente diferente: x=x+1 no es lo mismo si usa las dos palabras indistintamente.