Consecuencias de no comprender el casting en java.

Por descargarpseint / hace 2 meses / 0 Comentarios ».

Hoy tengo ganas de compartir contigo mi visión sobre como funciona el casting en java. Para ello voy a partir de un ejemplo expuesto en un debate de linkedin hace unos días. El problema te lo describo a continuación.

@Testpublic void testObtenerParteDecimalErroneo(){

int num1=57;

int num2=152; 

 int resultado = num1/num2 * 1000;

System.out.println(resultado);}

El objetivo de este código era obtener el resultado de 375, sin embargo, al ejecutarlo la respuesta que ofrece el programa es 0. ¿Qué está ocurriendo?.

Lo primero que tenemos que entender es que estamos manejando enteros de 32 bits. Lo cual quiere decir que los números que estamos tratando se están guardando en variables con ese número de bits.

El número 52 puede representarse en binario con 32 bits y el 152 también. Sin embargo, una vez hecho esto, intentamos dividirlos y el resultado no es lo que estábamos esperando. ¿Qué está haciendo java por debajo?. Devolviendo un entero y 0,375 no es un entero sino un real. La consecuencia de esto es que java va a realizar una división entera guardando esta parte en la variable resultado. (Ese inesperado cero).

Finalmente, multiplicar un número por 0 da como resultado cero. Así que de este pequeño análisis podemos concluir que el problema está en la división. Si queremos conservar la parte decimal del resultado tendremos que operar con variables que sean capaces de gestionar tanto la parte entera como la decimal del resultado de la división.

Los candidatos aquí son los tipos primitivos float y double. En el ejemplo son los valores 57 y 152, los cuales podrían almacenarse perfectamente en variables de tipo float (reales de 32 bits) convirtiéndose en los números 57.0 y 152.0. Además vamos a tener que almacenar el resultado en otra variable de tipo float.

float resultado = 57f/152f;

Una vez hecho esto, tendremos almacenado en la variable resultado el valor 0,375. ¿Qué ha cambiado respecto al código inicial?. Al pasar a trabajar con variables de coma flotante, la división se realiza a nivel de reales, calculando tanto la parte entera como decimal del resultado.

Hasta ahora no hemos realizado ningún casting explicito, es decir, programado por nosotros. Sin embargo, java siempre tiene en mente las posibles compatibilidades cuando se encuentra con asignaciones entre variables y también operaciones entre tipos primitivos.

Tras realizar la multiplicación por 1000 quizás podríamos pensar que ya tendríamos lo que deseamos (el 375), sin embargo, si pruebas a imprimir por pantalla la variable resultado obtendrás lo siguiente:

resultado = resultado * 1000; System.out.println(resultado); //El resultado de mostrar por pantalla la variable resultado es375.0

¿Por qué ese punto seguido por un cero final?.

La razón fundamental es que seguimos trabajando con reales (tipo float) y la representación gráfica de este tipo sigue el patrón (d+).(d+). Es decir, uno o mas dígitos, seguidos de un punto y finalmente de uno o mas dígitos.

Realizando un casting en java explicito de float a int.

Para conseguir el ansiado 375 vamos a tener que indicarle a java que lo que tenemos dentro de la variable resultado es un entero y no un real. Java, o mejor dicho, la maquina virtual que ejecuta todos los programas escritos en este lenguaje, no es mas que otro programa y como tal, tiene programadas una serie de reglas que sigue a rajatabla.

La JVM (Java Virtual Machine) solo sabe que el 375 está alojado dentro de una variable float, y por ello actúa en consecuencia. Si queremos que trate a nuestro resultado como un entero, entonces, tendremos que transformar la variable resultado en un int. Para indicarselo definiremos una nueva variable de tipo entera y le asignaremos la variable float.

int resultadoEntero = (int)resultado;

Antes de explicarte que significa el (int) intenta hacer la asignación directamente. El compilador se quejará mostrándote un mensaje como el siguiente

Type mismatch: cannot convert from float to int.

Lo que está diciéndonos es que no puede convertir un float en un entero. ¿Por qué?. Porque se podría perder información. Volviendo al ejemplo de la división, si tenemos el float 0,375 y java nos permitiera convertirlo en un int entonces tendríamos como resultado 0. Abríamos perdido la precisión de los decimales.

Sin embargo, quienes desarrollaron el lenguaje, sabían que situaciones como en la que nos encontramos en estos momentos se podían dar. ¿Existe alguna diferencia entre el 375 y el 375,0?. Para Java si pero para nosotros no tiene porqué. De esta forma nace el casting en java explicito que no es mas que una relajación en tipado fuerte de java para permitir realizar asignaciones (sin sentido desde el punto de vista del lenguaje) pero con mucho sentido para quienes hacemos uso de el.

A continuación te ofrezco como quedaría el código final

package com.programarenjava.tiposprimitivos; import static org.junit.Assert.*; import org.junit.Test; public class DividirDosNumerosTest { 

@Test

 public void testObtenerParteDecimal() {

float resultado = 57f/152f; 

resultado = resultado * 1000;

int resultadoEntero = (int)resultado; 

System.out.println(resultadoEntero); 

assertTrue(resultadoEntero==375);        } }

Por hoy tengo poco mas que comentarte. Si estoy muy interesando en conocer tus impresiones de tus experiencias con el casting en java tanto explicito como implícito. Para terminar quiero recordarte que tengo en mente nuevos tutoriales, incluso empezar a escribir mi primer libro, sobre tecnologías java porque son estas las que se demandan en el mercado y además mi experiencia está estrechamente relacionada con ellas.

Ver: como usar pseint algoritmos

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *