Honza Brabec
Hasta hoy, pensé que por ejemplo:
i += j;
Era solo un atajo para:
i = i + j;
Pero si probamos esto:
int i = 5;
long j = 8;
Entonces i = i + j;
no compilará pero i += j;
compilará bien.
¿Significa que de hecho i += j;
es un atajo para algo como esto
i = (type of i) (i + j)
?
lukas eder
Como siempre con estas preguntas, el JLS tiene la respuesta. En este caso §15.26.2 Operadores de asignación compuesta. Un extracto:
Una expresión de asignación compuesta de la forma
E1 op= E2
es equivalente aE1 = (T)((E1) op (E2))
dóndeT
es el tipo deE1
excepto esoE1
se evalúa una sola vez.
Un ejemplo citado de §15.26.2
[…] el siguiente código es correcto:
short x = 3; x += 4.6;
y da como resultado que x tenga el valor 7 porque es equivalente a:
short x = 3; x = (short)(x + 4.6);
En otras palabras, su suposición es correcta.
-
Entonces
i+=j
compila como lo verifiqué yo mismo, pero resultaría en una pérdida de precisión, ¿verdad? Si ese es el caso, ¿por qué no permite que suceda también en i=i+j? ¿Por qué molestarnos allí?– bad_keypoints
22 de septiembre de 2012 a las 6:07
-
@ronnieaka: Supongo que los diseñadores de lenguaje sintieron que en un caso (
i += j
), es más seguro asumir que se desea la pérdida de precisión a diferencia del otro caso (i = i + j
)– Lucas Eder
22 de septiembre de 2012 a las 8:31
pedro laurey
Un buen ejemplo de esta conversión es usar *= o /=
byte b = 10;
b *= 5.7;
System.out.println(b); // prints 57
o
byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40
o
char ch="0";
ch *= 1.1;
System.out.println(ch); // prints '4'
o
char ch="A";
ch *= 1.5;
System.out.println(ch); // prints 'a'
-
@AkshatAgarwal ch es un personaje. 65 * 1,5 = 97,5 -> ¿Entendido?
– Sajal Dutta
5 mayo 2014 a las 22:07
-
Sí, pero puedo ver a un principiante que viene aquí, lee esto y se va pensando que puede convertir cualquier carácter de mayúsculas a minúsculas multiplicándolo por 1.5.
– Dawud ibn Karim
28 de mayo de 2014 a las 9:25
-
@DavidWallace Cualquier personaje siempre que sea
A
😉– Peter Lawrey
28 mayo 2014 a las 12:56
-
@PeterLawrey y @DavidWallace revelaré su secreto–
ch += 32
=D– Minhas Kamal
16 de marzo de 2016 a las 5:29
Thirler
Muy buena pregunta. El Especificación del lenguaje Java confirma tu sugerencia.
Por ejemplo, el siguiente código es correcto:
short x = 3; x += 4.6;
y da como resultado que x tenga el valor 7 porque es equivalente a:
short x = 3; x = (short)(x + 4.6);
-
O más divertido: “int x=33333333; x+=1.0f;”.
– Super gato
20/04/2017 a las 19:31
-
@supercat, ¿qué truco es este? Una conversión de ampliación que se redondea incorrectamente, seguida de una adición que en realidad no cambia el resultado, y vuelve a convertir a int para producir un resultado que es muy inesperado para las mentes humanas normales.
– nexo
21 de septiembre de 2018 a las 12:33
-
@neXus: en mi humilde opinión, las reglas de conversión deberían haber tratado
double->float
como ampliación, sobre la base de que los valores de tipofloat
identificar los números reales menos específicamente que los de tipodouble
. Si uno vedouble
como dirección postal completa yfloat
como un código postal de 5 dígitos, es posible satisfacer una solicitud de un código postal con una dirección completa, pero no es posible especificar con precisión una solicitud de una dirección completa con solo un código postal. Convertir una dirección postal en un código postal es una operación con pérdidas, pero…– Super gato
21/09/2018 a las 15:05
-
…alguien que necesita una dirección completa generalmente no estaría pidiendo solo un código postal. Conversión de
float->double
es equivalente a convertir el código postal de EE. UU. 90210 con “US Post Office, Beverly Hills CA 90210”.– Super gato
21 de septiembre de 2018 a las 15:07
Umesh Awasti
Sí,
básicamente cuando escribimos
i += l;
el compilador convierte esto en
i = (int)(i + l);
acabo de comprobar el .class
código de archivo
Realmente es bueno saber
dku.rajkumar
tienes que lanzar desde long
a int
explicitly
en caso de i = i + l
luego compilará y dará la salida correcta. como
i = i + (int)l;
o
i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.
pero en caso de +=
simplemente funciona bien porque el operador hace implícitamente la conversión de tipos del tipo de variable derecha al tipo de variable izquierda, por lo que no es necesario convertirlos explícitamente.
-
En este caso, el “reparto implícito” podría tener pérdidas. En realidad, como dice @LukasEder en su respuesta, el elenco de
int
es interpretado después el+
. El compilador lanzaría (¿debería?) una advertencia si realmente emitiera ellong
aint
.– Romain
3 de enero de 2012 a las 10:17
slevy1
El problema aquí implica la conversión de tipos.
Cuando sumas int y long,
- El objeto int se convierte en largo y ambos se agregan y obtienes un objeto largo.
- pero el objeto largo no se puede convertir implícitamente a int. Entonces, tienes que hacerlo explícitamente.
Pero +=
está codificado de tal manera que hace una conversión de tipos. i=(int)(i+m)
-
En este caso, el “reparto implícito” podría tener pérdidas. En realidad, como dice @LukasEder en su respuesta, el elenco de
int
es interpretado después el+
. El compilador lanzaría (¿debería?) una advertencia si realmente emitiera ellong
aint
.– Romain
3 de enero de 2012 a las 10:17
En Java, las conversiones de tipo se realizan automáticamente cuando el tipo de la expresión en el lado derecho de una operación de asignación se puede promover con seguridad al tipo de la variable en el lado izquierdo de la asignación. Así podemos asignar con seguridad:
byte -> short -> int -> long -> float -> double.
Lo mismo no funcionará al revés. Por ejemplo, no podemos convertir automáticamente un largo a un int porque el primero requiere más almacenamiento que el segundo y, en consecuencia, se puede perder información. Para forzar tal conversión debemos realizar una conversión explícita.
Tipo – Conversión
-
oye, pero
long
es 2 veces más grande quefloat
.– Nombre para mostrar
30 de agosto de 2013 a las 10:17
-
A
float
no puede contener todo lo posibleint
valor, y undouble
no puede contener todo lo posiblelong
valor.– Alex CDM
09/09/2013 a las 20:41
-
¿Qué quiere decir con “convertido de forma segura”? De la última parte de la respuesta, puedo deducir que se refería a la conversión automática (transmisión implícita), lo que, por supuesto, no es cierto en el caso de float -> long. flotante pi = 3.14f; largo b = pi; dará como resultado un error del compilador.
– Lucas
7 de noviembre de 2013 a las 13:21
-
Sería mejor diferenciar los tipos primitivos de coma flotante con los tipos primitivos enteros. No son lo mismo.
– El águila pirotécnica
22 de diciembre de 2015 a las 20:59
-
Java tiene reglas de conversión simplistas que requieren el uso de conversiones en muchos patrones donde el comportamiento sin conversiones coincidiría con las expectativas, pero no requiere conversiones en muchos patrones que generalmente son erróneos. Por ejemplo, un compilador aceptará
double d=33333333+1.0f;
sin quejarse, aunque el resultado 33333332.0 probablemente no sea lo que se pretendía (por cierto, la respuesta aritméticamente correcta de 33333334.0f se podría representar comofloat
oint
).– Super gato
20/04/2017 a las 19:40
Me sorprende que Java permita esto, siendo un lenguaje más estricto que sus predecesores. Los errores en la conversión pueden provocar fallas críticas, como fue el caso del vuelo 501 de Ariane5, donde una conversión flotante de 64 bits a un entero de 16 bits resultó en el bloqueo.
– SQLDiver
5 de enero de 2015 a las 16:31
En un sistema de control de vuelo escrito en Java, esta sería la menor de sus preocupaciones @SQLDiver
– Ross Drew
2 de noviembre de 2015 a las 9:24
De hecho
i+=(long)j;
incluso se compilará bien.– Tharindu Sathischandra
18 de marzo de 2016 a las 7:45
El impulso constante de un conjunto de desarrolladores por la precisión y otro por la facilidad de uso es realmente interesante. Casi necesitamos dos versiones del lenguaje, una que sea asombrosamente precisa y otra que sea fácil de usar. Empujar a Java desde ambas direcciones hace que no sea adecuado para ninguno de los dos grupos.
– Bill K.
19 de septiembre de 2017 a las 16:03
si requiriera casting, ¿dónde lo pondrías?
i += (int) f;
arroja f antes de la suma, por lo que no es equivalente.(int) i += f;
arroja el resultado después de la asignación, tampoco es equivalente. no habría lugar para colocar una conversión que significaría que desea convertir el valor después de agregar, pero antes de la asignación.– Tempestad de Norill
24 de octubre de 2018 a las 13:09