Quiero ser mejor sobre saber cuándo debo lanzar. ¿Cuáles son las reglas de conversión de tipo implícito en C ++ al agregar, multiplicar, etc. Por ejemplo,
int + float = ?
int * float = ?
float * int = ?
int / float = ?
float / int = ?
int / int = ?
int ^ float = ?
etcétera...
¿Se evaluará siempre la expresión como el tipo más preciso? ¿Las reglas difieren para Java? Corríjame si he formulado esta pregunta de manera incorrecta.

^es XOR.Respuestas:
En C ++, los operadores (para los tipos de POD) siempre actúan sobre objetos del mismo tipo.
Por lo tanto, si no son iguales, se promoverá uno para que coincida con el otro.
El tipo del resultado de la operación es el mismo que el de los operandos (después de la conversión).
Nota. El tamaño mínimo de las operaciones es
int. Entoncesshort/charson promovidos aintantes de que se realice la operación.En todas sus expresiones,
intse promueve afloatantes de que se realice la operación. El resultado de la operación es afloat.fuente
char. Si el valor dechar + charse asigna a achar, entonces solo puede hacer la aritméticachary, por ejemplo, ajustar. Pero si se asigna el resultado,intentonces tiene que hacer la aritmética en un tipo lo suficientemente grande como para obtener el resultado correcto cuando es más queCHAR_MAX.((int) 4) - ((unsigned int) 5)dará como resultado4294967295entradas de 32 bits y entradas de 32 bits sin signo.Operaciones aritméticas que implican
floatresultados enfloat.Para más detalles responda. Mire lo que dice la sección §5 / 9 del Estándar C ++
fuente
doubletampocolong double.long longyunsigned longno se aborda aquí.floatno tiene suficientes bits en la mantisa (24 bits para IEEE-754 ) para un 32 bitsint, por lo que puede haber alguna pérdida de datos. Un 64 bitsdoubledebería estar bien.Como las otras respuestas no hablan sobre las reglas en C ++ 11, aquí hay una. Del estándar C ++ 11 (borrador n3337) §5 / 9 (enfatizó la diferencia):
Vea aquí una lista que se actualiza con frecuencia.
fuente
Esta respuesta está dirigida en gran parte a un comentario hecho por @ RafałDowgird:
Tenga en cuenta que el estándar C ++ tiene la importante regla "como si". Ver sección 1.8: Ejecución del programa:
El compilador no puede establecer un
inttamaño de 8 bits, incluso si fuera el más rápido, ya que el estándar exige un mínimo de 16 bitsint.Por lo tanto, en el caso de una computadora teórica con operaciones súper rápidas de 8 bits, la promoción implícita
intde aritmética podría ser importante. Sin embargo, para muchas operaciones, no puede saber si el compilador realmente realizó las operaciones con la precisión de aninty luego se convirtió en acharpara almacenar en su variable, o si las operaciones se realizaron en char todo el tiempo.Por ejemplo, considere
unsigned char = unsigned char + unsigned char + unsigned chardónde se desbordaría la suma (supongamos un valor de 200 para cada uno). Si ascendieras aint, obtendrías 600, que luego se convertirían implícitamente en ununsigned char, que envolvería el módulo 256, dando así un resultado final de 88. Si no hicieras tales promociones, tendrías que envolver entre el primer dos adiciones, lo que reduciría el problema de200 + 200 + 200a144 + 200, que es 344, que se reduce a 88. En otras palabras, el programa no conoce la diferencia, por lo que el compilador es libre de ignorar el mandato de realizar operaciones intermediasintsi los operandos tienen una clasificación más baja queint.Esto es cierto en general de suma, resta y multiplicación. No es cierto en general para la división o el módulo.
fuente
Si excluye los tipos sin firmar, hay una jerarquía ordenada: char firmado, short, int, long, long long, float, double, long double. Primero, todo lo que venga antes de int en lo anterior se convertirá a int. Luego, en una operación binaria, el tipo de clasificación inferior se convertirá en el superior y los resultados serán del tipo superior. (Notará que, desde la jerarquía, cada vez que intervienen un punto flotante y un tipo integral, el tipo integral se convertirá al tipo de punto flotante).
Unsigned complica un poco las cosas: perturba la clasificación y partes de la clasificación se definen como implementación. Debido a esto, es mejor no mezclar con y sin signo en la misma expresión. (La mayoría de los expertos en C ++ parecen evitar sin firmar a menos que estén involucradas operaciones bit a bit. Al menos, eso es lo que recomienda Stroustrup).
fuente
intpara un número que nunca necesita ser negativo es un desperdicio completo de un 50% del rango disponible. Ciertamente no soy Stroustrup, pero lo usounsignedpor defecto ysignedsolo cuando tengo una razón.bool in_order(vector<T> vec) { for ( int i = 0; i < size() - 1; ++i) { if (vec[i + 1] < vec[i]) return false; } return true;y luego se molestaría al descubrir que se bloquea por vectores vacíos porque size () - 1 devuelve 18446744073709551615.Mi solución al problema tiene WA (respuesta incorrecta), entonces me cambió uno de
intalong long inty se la dio CA (aceptar) . Anteriormente, estaba tratando de hacerlolong long int += int * int, y luego lo rectificolong long int += long long int * int. Google se me ocurrió,1. Conversiones aritméticas
Condiciones para la conversión de tipo:
Condiciones cumplidas ---> Conversión
Cualquiera de los operandos es de tipo largo doble . ---> Otro operando se convierte a tipo largo doble .
Condición anterior no cumplida y cualquiera de los operandos es de tipo doble . ---> Otro operando se convierte al tipo double .
No se cumplen las condiciones anteriores y cualquiera de los operandos es de tipo flotante . ---> Otro operando se convierte a tipo flotante .
Condiciones anteriores no cumplidas (ninguno de los operandos son de tipo flotante). ---> Las promociones integrales se realizan en los operandos de la siguiente manera:
2) Reglas de conversión de enteros
Los tipos enteros más pequeños que int se promueven cuando se realiza una operación en ellos. Si todos los valores del tipo original se pueden representar como un int, el valor del tipo más pequeño se convierte en un int; de lo contrario, se convierte en un int sin signo. Las promociones de enteros se aplican como parte de las conversiones aritméticas habituales a ciertas expresiones de argumento; operandos de los operadores unarios +, - y ~; y operandos de los operadores de turno.
Rango de conversión de enteros:
long long intserá mayor que el rango delong int, que será mayor que el rango deint, que será mayor que el rango deshort int, que será mayor que el rango designed char.charserá igual al rango designed charyunsigned char.Conversiones aritméticas habituales:
fuente
Todo el capítulo 4 habla sobre las conversiones, pero creo que debería interesarle principalmente:
4.5 Promociones integrales [conv.prom]
Un valor r de tipo char, char firmado, unsigned char, short int o unsigned short int se puede convertir en un rvalue de tipo int si int puede representar todos los valores del tipo fuente; de lo
contrario, el valor r de origen se puede convertir a un valor r de tipo unsigned int.
Un valor r de tipo wchar_t (3.9.1) o un tipo de enumeración (7.2) se puede convertir en un valor r del primero
de los siguientes tipos que puede representar todos los valores de su tipo subyacente: int, unsigned int,
long o unsigned largo.
Un valor r para un campo de bits integral (9.6) se puede convertir en un valor r de tipo int si int puede representar todos
los valores del campo de bits; de lo contrario, se puede convertir a unsigned int si unsigned int puede repetir
reenviar todos los valores del campo de bits. Si el campo de bits es aún mayor, no se aplica ninguna promoción integral. Si el
campo de bits tiene un tipo enumerado, se trata como cualquier otro valor de ese tipo para fines de promoción.
Un valor de tipo bool se puede convertir en un valor de tipo int, con falso convirtiéndose en cero y verdadero
convirtiéndose en uno.
Estas conversiones se llaman promociones integrales.
4.6 Promoción de punto flotante [conv.fpprom]
Un valor de tipo flotante se puede convertir en un valor de tipo doble. El valor no ha cambiado.
Esta conversión se llama promoción de punto flotante.
Por lo tanto, todas las conversiones que involucran flotante - el resultado es flotante.
Solo el que involucra ambos int: el resultado es int: int / int = int
fuente
El tipo de la expresión, cuando no ambas partes son del mismo tipo, se convertirá en la mayor de ambas. El problema aquí es entender cuál es más grande que la otra (no tiene nada que ver con el tamaño en bytes).
En las expresiones en las que están involucrados un número real y un número entero, el número entero será promovido a número real. Por ejemplo, en int + float, el tipo de expresión es float.
La otra diferencia está relacionada con la capacidad del tipo. Por ejemplo, una expresión que involucra un int y un int largo resultará del tipo long int.
fuente
longes "más grande" que afloatpero ¿cuál es el tipo delong+float?¡Consideración!
Las conversiones ocurren de izquierda a derecha.
Prueba esto:
fuente
j + i * kdaría como resultado 101.