suma programacion programa para operaciones multiplicar multiplicacion hacer como codigo basicas aritmeticas c++ c casting

programacion - programa para multiplicar en c++



¿Qué variables debería encasillar al hacer operaciones matemáticas en C/C++? (9)

Por ejemplo, cuando estoy dividiendo dos entradas y quiero que me devuelvan una carroza, escribo supersticiosamente algo como esto:

int a = 2, b = 3; float c = (float)a / (float)b;

Si no lanzo b para flotar, hará división de enteros y devolverá un int.

De manera similar, si quiero multiplicar un número de 8 bits con un número de 8 bits sin signo, los enviaré a números de 16 bits con signo antes de multiplicarlos por temor a un desbordamiento:

u8 a = 255; s8 b = -127; s16 = (s16)a * (s16)b;

¿Cómo se comporta exactamente el compilador en estas situaciones cuando no está emitiendo nada o cuando solo proyecta una de las variables? ¿Realmente necesito lanzar explícitamente todas las variables, o solo la de la izquierda, o la de la derecha?


¿Necesitas lanzar uno o dos lados? La respuesta no está dictada por el compilador. Tiene que saber las reglas exactas y previas. En cambio, la respuesta debe ser dictada por la persona que leerá el código más tarde. Por esa sola razón, coloca ambos lados del mismo tipo. El truncamiento implícito podría ser lo suficientemente visible, de modo que el molde podría ser redundante.

por ejemplo, este elenco flotante-> int es obvio.

int a = float(foo()) * float(c);


Creo que siempre que estés emitiendo solo una de las dos variables, el compilador se comportará correctamente (al menos en los compiladores que conozco).

Entonces todo de:

flotar c = (flotar) a / b;

float c = a / (float) b;

flotar c = (flotar) a / (flotar) b;

tendrá el mismo resultado.


Después de haber trabajado en sistemas críticos para la seguridad, tiendo a ser paranoico y siempre conjuro ambos factores: flotar (a) / flotar (b) - por si acaso un sutil gotcha planea morderme más tarde. No importa cuán bueno sea el compilador, sin importar cuán bien definidos estén los detalles en las especificaciones del lenguaje oficial. Paranoia: ¡el mejor amigo de un programador!


División de enteros: lanzar cualquiera de los operandos, sin necesidad de lanzarlos a los dos. Si ambos operandos son enteros, la operación de división es una división entera; de lo contrario, es una división de coma flotante.

En cuanto a la pregunta de desbordamiento, no hay necesidad de emitir explícitamente, ya que el compilador lo hace implícitamente por usted:

#include <iostream> #include <limits> using namespace std; int main() { signed int a = numeric_limits<signed int>::max(); unsigned int b = a + 1; // implicit cast, no overflow here cout << a << '' '' << b << endl; return 0; }


En el caso de la división de coma flotante, siempre que una variable sea de un tipo de datos de coma flotante (flotante o doble), la otra variable se ampliará a un tipo de coma flotante y se producirá una división de coma flotante; así que no hay necesidad de lanzar ambos a una carroza.

Habiendo dicho eso, de todos modos, siempre lancé los dos a una carroza.


En general, si los operandos son de tipos diferentes, el compilador promocionará todo al tipo más grande o más preciso:

If one number is... And the other is... The compiler will promote to... ------------------- ------------------- ------------------------------- char int int signed unsigned unsigned char or int float float float double double

Ejemplos:

char + int ==> int signed int + unsigned char ==> unsigned int float + int ==> float

Sin embargo, tenga en cuenta que la promoción solo ocurre según lo requerido para cada cálculo intermedio, por lo tanto:

4.0 + 5/3 = 4.0 + 1 = 5.0

Esto se debe a que la división entera se realiza primero, luego el resultado se promueve a flotar para la suma.


Luego, hay tipos más antiguos con daño cerebral como yo que, teniendo que usar lenguajes anticuados, escriben cosas sin pensar como

int a; int b; float z; z = a*1.0*b;

Por supuesto, esto no es universal, es bueno solo para casi este caso.


Puedes simplemente lanzar uno de ellos. Sin embargo, no importa cuál.

Siempre que los tipos no coincidan, el tipo "más pequeño" se promociona automáticamente al tipo "más grande", siendo el punto flotante "más grande" que los tipos enteros.


Pregunta 1: división del flotador

int a = 2, b = 3; float c = static_cast<float>(a) / b; // need to convert 1 operand to a float

Pregunta 2: Cómo funciona el compilador

Cinco reglas generales para recordar:

  • Las operaciones aritméticas siempre se realizan en valores del mismo tipo.
  • El tipo de resultado es el mismo que los operandos (después de la promoción)
  • Las operaciones aritméticas de tipo más pequeñas se realizan en int.
  • ANSCI C (y, por lo tanto, C ++) usan valor que preserva la promoción de enteros.
  • Cada operación se realiza de forma aislada .

Las reglas de ANSI C son las siguientes:
La mayoría de estas reglas también se aplican a C ++, aunque no todos los tipos son oficialmente compatibles (todavía).

  • Si cualquiera de los dos operandos es un doble largo, el otro se convierte en un doble largo .
  • Si cualquiera de los dos operandos es doble, el otro se convierte a doble .
  • Si cualquiera de los operandos es flotante, el otro se convierte en flotante .
  • Si cualquiera de los operandos tiene un largo sin signo, el otro se convierte en largo sin signo .
  • Si cualquiera de los operandos es de larga duración, el otro se convierte en long long .
  • Si cualquiera de los operandos tiene un largo sin signo, el otro se convierte en largo sin signo .
  • Si cualquiera de los operandos es largo, el otro se convierte en largo .
  • Si cualquier operando es unsigned int el otro se convierte a unsigned int .
  • De lo contrario, ambos operandos se convierten a int .

Rebosar

El desbordamiento siempre es un problema. Nota. El tipo de resultado es el mismo que el de los operandos de entrada, por lo que todas las operaciones pueden desbordarse, por lo que sí debe preocuparse (aunque el lenguaje no proporciona ninguna forma explícita de detectar esto).

Como nota al margen:
La división sin firmar no puede desbordarse, pero la división firmada puede.

std::numeric_limits<int>::max() / -1 // No Overflow std::numeric_limits<int>::min() / -1 // Will Overflow