Variables en Java práctica — el recibo, la nota final y el carné de Laura (con la nota que salía 0.0)

La semana antes del primer práctico de FP2, un compañero de mi grupo programó la nota final ponderada de la asignatura: 60 % de teoría, 40 % de prácticas. Compiló a la primera, lo ejecutó con sus notas… y le salió un 0.0. Revisó las notas, revisó los porcentajes, revisó hasta que el archivo fuera el bueno. El fallo estaba en una sola expresión: 60 / 100. Dos int, división entera: cero. Y cero por cualquier nota es cero.

Esa es la lección de esta práctica: con variables en Java, el programa casi nunca se queja. Compila, se ejecuta y te da un número. El trabajo es saber si ese número es el bueno.

Aquí vas a escribir tres programas sobre la misma estudiante de los artículos de sintaxis, Laura (datos inventados), y en los tres hay una trampa de la teoría de variables en Java esperando: el recibo de matrícula con un descuento y cuatro plazos repartidos en céntimos, la nota final de FP2 con medias y pesos, y el carné universitario, con un usuario hecho a base de char y un expediente que no cabe en un int. Los tres son de nivel medio y usan datos que se parecen a los de verdad: porcentajes guardados como enteros, céntimos que no se reparten exactos, textos construidos al ejecutar. Y ninguno usa todavía Scanner, if ni bucles: los datos van escritos en el programa, que es lo que toca en este tema.

Antes de empezar

Conviene tener claro:

  • Los tipos int, long, double, char, boolean y String, y cuándo usar cada uno.
  • Que int / int da int y que el cast tiene que ir antes de dividir.
  • Que el desbordamiento de int no avisa y que la L va en el primer número de la cuenta.
  • Que los textos se comparan con equals(), no con ==.

Si alguno te suena dudoso, repasa la teoría antes de seguir.

Cada programa es una clase con main en su propio archivo, que se llama como la clase (Matricula.java, NotaFinal.java, Carne.java). Compílalos con javac Matricula.java y ejecútalos con java Matricula, o pégalos en el entorno de Java de la web con «Abrir en el entorno». Si tu equipo está en inglés, printf escribirá los decimales con punto en lugar de coma: es normal.

Programa 1: el recibo de matrícula sin datos repetidos

Laura tiene 24 créditos a 15,50 €, un descuento del 25 % sobre los créditos (no sobre la tasa) y una tasa de secretaría de 27,30 €. Quiere pagar en cuatro plazos. El programa tiene que calcular el recibo y repartir el total en plazos sin perder ni un céntimo. Lo que lo complica: el porcentaje viene como un entero (25) y 306,30 € no se divide exacto entre cuatro.

La idea

  1. Lo que no cambia va en constantes final: precio del crédito, tasa y número de plazos. Cada número se escribe una sola vez.
  2. Las cuentas en double: importe de los créditos, descuento y total.
  3. El descuento lo calculamos dos veces, mal y bien, para ver la división entera en acción.
  4. Para los plazos pasamos el total a céntimos enteros (int): así / reparte y % dice cuántos céntimos sobran, sin decimales que se pierdan por el camino. El último plazo se queda lo que sobra.

Antes de programar, piensa en qué tipo tiene cada resultado intermedio. descuentoPorcentaje / 100 mezcla dos int: ¿qué da 25 / 100?

El código

/**
 * Programa 1: el recibo de matrícula de Laura, con cada dato en su variable.
 * Datos inventados: 24 créditos a 15,50 €, tasa de secretaría de 27,30 €, descuento del 25 % y 4 plazos.
 */
public class Matricula {
    public static void main(String[] args) {
        // Datos que no cambian en todo el programa: constantes
        final double PRECIO_CREDITO = 15.50;
        final double TASA_SECRETARIA = 27.30;
        final int PLAZOS = 4;

        // Datos de Laura
        String estudiante = "Laura Santana Ruiz";
        int creditos = 24;
        int descuentoPorcentaje = 25;                              // 25 %, guardado como entero

        // Cuentas
        double importeCreditos = creditos * PRECIO_CREDITO;        // int * double = double
        double descuentoMal = descuentoPorcentaje / 100 * importeCreditos;   // 25 / 100 = 0 (int)
        double descuentoBien = descuentoPorcentaje / 100.0 * importeCreditos; // 25 / 100.0 = 0.25
        double total = importeCreditos - descuentoBien + TASA_SECRETARIA;

        // Plazos en céntimos: enteros exactos, sin decimales que se pierdan
        int totalCentimos = (int) Math.round(total * 100);         // 306,30 € → 30630
        int plazoCentimos = totalCentimos / PLAZOS;                // división entera
        int sobran = totalCentimos % PLAZOS;                       // céntimos que no reparte
        int ultimoPlazo = plazoCentimos + sobran;                  // el último paga lo que sobra

        System.out.println("RECIBO DE MATRÍCULA");
        System.out.println("Estudiante: " + estudiante);
        System.out.printf("%-26s %8.2f €%n", creditos + " créditos x " + PRECIO_CREDITO, importeCreditos);
        System.out.printf("%-26s %8.2f €%n", "Descuento (int / 100)", -descuentoMal);
        System.out.printf("%-26s %8.2f €%n", "Descuento (int / 100.0)", -descuentoBien);
        System.out.printf("%-26s %8.2f €%n", "Tasa de secretaría", TASA_SECRETARIA);
        System.out.printf("%-26s %8.2f €%n", "TOTAL", total);
        System.out.println("En céntimos: " + totalCentimos);
        System.out.printf("%d plazos de %.2f € y el último de %.2f € (sobran %d céntimos)%n",
                PLAZOS - 1, plazoCentimos / 100.0, ultimoPlazo / 100.0, sobran);
        System.out.println("Comprobación: " + (plazoCentimos * (PLAZOS - 1) + ultimoPlazo) + " céntimos");
    }
}

La parte de los plazos, de cerca:

// Plazos en céntimos: enteros exactos, sin decimales que se pierdan
int totalCentimos = (int) Math.round(total * 100);         // 306,30 € → 30630
int plazoCentimos = totalCentimos / PLAZOS;                // división entera
int sobran = totalCentimos % PLAZOS;                       // céntimos que no reparte
int ultimoPlazo = plazoCentimos + sobran;                  // el último paga lo que sobra

Math.round(total * 100) pasa 306,30 a 30630 céntimos. ¿Por qué Math.round y no un cast? Porque total * 100 es un double y podría salir algo como 30629,999999… por la forma en que se guardan los decimales; el cast lo dejaría en 30629 y perderías un céntimo. Math.round redondea al entero más cercano y devuelve un long; el (int) de delante lo baja a int porque sabemos que cabe.

Salida

RECIBO DE MATRÍCULA
Estudiante: Laura Santana Ruiz
24 créditos x 15.5           372,00 €
Descuento (int / 100)         -0,00 €
Descuento (int / 100.0)      -93,00 €
Tasa de secretaría            27,30 €
TOTAL                        306,30 €
En céntimos: 30630
3 plazos de 76,57 € y el último de 76,59 € (sobran 2 céntimos)
Comprobación: 30630 céntimos

Comprobemos a mano:

PasoCuentaResultado
Importe de los créditos24 × 15,50372,00 €
Descuento mal25 / 100 = 0 → 0 × 3720 €
Descuento bien25 / 100.0 = 0.25 → 0.25 × 37293,00 €
Total372 − 93 + 27,30306,30 €
En céntimos306,30 × 10030630
Plazo30630 / 47657
Sobran30630 % 42
Último plazo7657 + 27659
Comprobación7657 × 3 + 765930630
Los cuatro plazos de la matrícula306,30 euros son 30630 céntimos. 30630 / 4 da 7657 céntimos por plazo y 30630 % 4 da 2 céntimos que sobran; el último plazo es 7659. 7657 por 3 más 7659 suma 30630.306,30 € → 30630céntimos (int)30630 / 4 = 765730630 % 4 = 2Plazo 17657Plazo 27657Plazo 37657Plazo 476597657 + 2 que sobran7657 × 3 + 7659 = 30630No se pierde ni un céntimo: / reparte y % dice lo que queda
Con enteros, / y % trabajan juntos: uno reparte y el otro guarda lo que no se pudo repartir.

Tres detalles de la salida que merecen una mirada:

  • La primera línea dice 24 créditos x 15.5: el texto se ha construido con +, que escribe el double a la manera de Java (punto y sin el cero). El importe de la derecha va con printf y sale 372,00. Es la diferencia entre concatenar y formatear que viste en la sintaxis.
  • El descuento mal sale -0,00, con signo: -descuentoMal es «menos cero», y en los double el cero negativo existe. No cambia ninguna cuenta, pero en un recibo de verdad quedaría feo.
  • plazoCentimos / 100.0 vuelve a euros para imprimir: con / 100 (entero) saldrían 76 € justos.

Preguntas que te puedes hacer

¿Por qué no guardar el porcentaje directamente como 0.25? Podrías, y te ahorrarías la trampa. Pero en los programas reales los porcentajes llegan muchas veces como enteros (de un formulario, de una base de datos, de un enunciado que dice «25 %»), y tienes que saber convertirlos sin perder nada.

¿Por qué repartir en céntimos y no dividir 306,30 entre 4? Porque 306,30 / 4 = 76,575, que no es un importe que se pueda cobrar. Habría que redondear cada plazo, y cuatro plazos redondeados no tienen por qué sumar el total. En céntimos enteros, / y % lo dejan cuadrado por construcción.

¿Por qué el último plazo y no el primero? Es una decisión de diseño: muchas facturas cargan el ajuste en la última cuota. Si quisieras cargarlo en la primera, cambias ultimoPlazo por primerPlazo y el texto. La cuenta es la misma.

¿Qué pasaría con int totalCentimos = total * 100;? No compilaría: double a int es un estrechamiento y javac pide el cast (possible lossy conversion). Y con el cast pero sin Math.round, te expones a perder el céntimo del que hablábamos.

¿Hace falta final si nadie va a cambiar esas variables? No para que funcione, pero final deja escrito que son constantes y el compilador te protege si un día alguien (tú, a las tres de la mañana) intenta reasignarlas.

Escribir el porcentaje como descuento / 100 * importe con descuento entero. La división entera lo deja en 0 y el programa calcula un descuento de cero euros sin ningún aviso. Escribe / 100.0.

Para el dinero, céntimos en un int o un long. Sumar, repartir y comparar enteros es exacto; con double arrastras pequeños errores que, a veces, se ven.

Pruébalo tú

  1. Cambia PLAZOS a 3 y luego a 7. ¿Cuántos céntimos sobran en cada caso? Comprueba que la línea de comprobación sigue dando 30630.
  2. Haz que el descuento sea del 12 % y que también se aplique sobre la tasa. ¿Cuánto paga Laura ahora? Calcúlalo a mano antes de ejecutar.

Programa 2: la nota final de FP2

Ahora la historia del compañero, pero con las notas de Laura: dos parciales enteros (7 y 8) que hacen la media de teoría, una práctica con medio punto (6,5) y unos pesos del 60 % y el 40 % guardados como enteros. El programa calcula la media y la nota final de varias formas para ver cuáles fallan, y después decide qué se apunta en el acta: truncar, redondear o un decimal.

La idea

  1. La media de teoría escrita de tres maneras: sin decimales, con el cast después y dividiendo entre 2.0.
  2. La ponderación con / 100 y con / 100.0.
  3. Tres maneras de quedarse con la nota final: (int), Math.round y redondear a un decimal multiplicando y dividiendo por 10.
  4. Todo con println para ver el número tal cual lo guarda Java, y una última línea con printf para comparar.

Antes de ejecutar, apunta en un papel lo que crees que va a salir en cada línea. Las que fallen son las que tienes que entender.

El código

/**
 * Programa 2: la nota final de FP2 de Laura (pesos y notas inventados).
 * Parcial 1 y parcial 2 hacen la media de teoría (60 %) y la práctica pesa el 40 %.
 */
public class NotaFinal {
    public static void main(String[] args) {
        int parcial1 = 7;                    // las notas de los parciales son enteras
        int parcial2 = 8;
        double practica = 6.5;               // la práctica se puntúa con medio punto
        int pesoTeoria = 60;                 // porcentajes guardados como int
        int pesoPractica = 40;

        // 1. La media de teoría: tres formas de escribirla
        int mediaInt = (parcial1 + parcial2) / 2;                       // 15 / 2 = 7
        double mediaTarde = (double) ((parcial1 + parcial2) / 2);       // el cast llega tarde: 7.0
        double mediaTeoria = (parcial1 + parcial2) / 2.0;               // 15 / 2.0 = 7.5

        // 2. La ponderación: el mismo fallo, ahora con los porcentajes
        double finalMal = pesoTeoria / 100 * mediaTeoria + pesoPractica / 100 * practica;
        double finalBien = pesoTeoria / 100.0 * mediaTeoria + pesoPractica / 100.0 * practica;

        // 3. Lo que se apunta en el acta
        int truncada = (int) finalBien;                  // quita los decimales
        long redondeada = Math.round(finalBien);         // redondea (devuelve long)
        double unDecimal = Math.round(finalBien * 10) / 10.0;   // redondear a un decimal

        System.out.println("Media de teoría (int):         " + mediaInt);
        System.out.println("Media de teoría (cast tarde):  " + mediaTarde);
        System.out.println("Media de teoría (2.0):         " + mediaTeoria);
        System.out.println("Nota final (int / 100):        " + finalMal);
        System.out.println("Nota final (int / 100.0):      " + finalBien);
        System.out.println("Truncada con (int):            " + truncada);
        System.out.println("Redondeada con Math.round:     " + redondeada);
        System.out.println("A un decimal:                  " + unDecimal);
        System.out.printf("Con printf y %%.2f:             %.2f%n", finalBien);
    }
}

Salida

Media de teoría (int):         7
Media de teoría (cast tarde):  7.0
Media de teoría (2.0):         7.5
Nota final (int / 100):        0.0
Nota final (int / 100.0):      7.1
Truncada con (int):            7
Redondeada con Math.round:     7
A un decimal:                  7.1
Con printf y %.2f:             7,10
La misma trampa en la media y en los pesosMedia: (7 + 8) / 2 da 7, el cast después da 7.0 y dividir entre 2.0 da 7.5. Ponderación: 60 / 100 y 40 / 100 dan 0, así que la nota sale 0.0; con 100.0 sale 4.5 + 2.6 = 7.1.La media de teoríaLa ponderación 60 / 40(7 + 8) / 2→ 15 / 2 = 7(double) ((7 + 8) / 2)→ (double) 7 = 7.0(7 + 8) / 2.0→ 15 / 2.0 = 7.560 / 100 * 7.5→ 0 * 7.5 = 0.040 / 100 * 6.5→ 0 * 6.5 = 0.060 / 100.0 * 7.5 + 40 / 100.0 * 6.5→ 4.5 + 2.6 = 7.1int / int da int, y el cast o el double de la izquierda llegan tarde: el decimal tiene que estar dentro
Las dos columnas fallan por lo mismo: una división entre dos int antes de que aparezca ningún decimal.

Línea a línea, con la cuenta hecha a mano:

LíneaExpresiónCuentaSale
Media (int)(7 + 8) / 215 / 2 entera7
Media (cast tarde)(double) ((7 + 8) / 2)primero 15 / 2 = 7, luego 7.07.0
Media (2.0)(7 + 8) / 2.015 / 2.07.5
Final mal60 / 100 * 7.5 + 40 / 100 * 6.50 × 7.5 + 0 × 6.50.0
Final bien60 / 100.0 * 7.5 + 40 / 100.0 * 6.54.5 + 2.67.1
Truncada(int) 7.1quita decimales7
RedondeadaMath.round(7.1)al entero más cercano7
Un decimalMath.round(7.1 * 10) / 10.071 / 10.07.1

La línea de 0.0 es la nota del compañero. Fíjate en que las dos mitades de la suma fallan a la vez: 60 / 100 y 40 / 100 son cero, así que da igual lo buenas que sean las notas.

Preguntas que te puedes hacer

¿Por qué Math.round(finalBien * 10) / 10.0 redondea a un decimal? Multiplicar por 10 mueve la coma un sitio (7.1 → 71.0), Math.round redondea al entero (71) y dividir entre 10.0 la devuelve a su sitio (7.1). Con / 10 (entero) perderías el decimal que querías conservar: 71 / 10 = 7.

¿Truncar o redondear? Depende de la norma de la asignatura. Con 7.1 da igual, pero con un 4,96 truncar da un 4 (suspenso) y redondear da un 5. Por eso es importante saber que (int) no redondea.

¿Por qué long redondeada y no int? Porque Math.round con un double devuelve long. Si quieres un int, (int) Math.round(finalBien), como en el programa 1.

¿Y si las notas de los parciales también tuvieran decimales? Entonces serían double y (parcial1 + parcial2) / 2 ya daría bien, porque uno de los operandos de la división sería decimal. La trampa solo aparece cuando todo lo que hay a la izquierda de la división es entero.

¿Por qué la última línea dice 7,10 con coma? printf con %.2f usa el idioma del equipo (español: coma) y siempre dos decimales. println escribe 7.1, a la manera de Java. Para mostrar notas a una persona, printf.

Escribir los pesos como peso / 100 con peso entero (o el porcentaje del programa 1, que es lo mismo). Cada vez que veas una división, pregúntate de qué tipo son los dos lados.

Pruébalo tú

  1. Cambia practica a 4.95 y averigua (antes de ejecutar) qué dan la nota truncada, la redondeada y la de un decimal.
  2. Añade un tercer parcial con nota 9 y calcula la media de teoría de los tres sin que se pierdan los decimales.

Programa 3: el carné universitario

El último programa genera los datos del carné de Laura: el usuario de la universidad (inicial del nombre más el primer apellido, en minúsculas), su correo, el número de expediente (año de ingreso seguido del número de alumno: 20260004321) y una letra de control calculada como la del DNI. Al final comprueba si el usuario coincide con el que tiene la secretaría. Lo que lo complica: la inicial hay que pasarla a minúscula con aritmética de char, el expediente tiene once cifras y la comparación de textos tiene su trampa.

La idea

  1. La inicial: charAt(0) da 'L'. En ASCII, la distancia entre mayúscula y minúscula es 32 ('a' − 'A' = 97 − 65), así que (char) (inicial + 32) da 'l'.
  2. El usuario: un char más un String da un String. apellido1.toLowerCase() pone el apellido en minúsculas.
  3. El expediente: año × 10.000.000 + número de alumno. 2026 × 10.000.000 = 20.260.000.000, que no cabe en un int: lo calculamos dos veces, en int (mal) y en long (bien).
  4. La letra: el resto de dividir el expediente entre 23 elige una letra de la cadena TRWAGMYFPDXBNJZSQVHLCKE, la misma que usa el DNI español.
  5. La comparación: con == y con equals().

Antes de programar, piensa en el tipo de inicial + 32. ¿Es un char?

El código

/**
 * Programa 3: el carné universitario de Laura (datos inventados).
 * Usuario hecho con char y String, expediente que no cabe en un int y la comparación de textos.
 */
public class Carne {
    public static void main(String[] args) {
        String nombre = "Laura";
        String apellido1 = "Santana";
        int anioIngreso = 2026;
        int numeroAlumno = 4321;

        // El usuario: inicial del nombre + primer apellido, en minúsculas
        char inicial = nombre.charAt(0);                     // 'L'
        char inicialMin = (char) (inicial + 32);             // en ASCII, 'a' - 'A' = 32
        String usuario = inicialMin + apellido1.toLowerCase();   // char + String = String
        System.out.println("Usuario:     " + usuario);
        System.out.println("Correo:      " + usuario + "@alu.ulpgc.es");

        // El expediente: año * 10 000 000 + número de alumno = 20260004321 (11 cifras)
        int expedienteMal = anioIngreso * 10000000 + numeroAlumno;     // pasa de 2 147 483 647
        long expediente = anioIngreso * 10000000L + numeroAlumno;      // 10000000L: cuenta en long
        System.out.println("Expediente (int):  " + expedienteMal);
        System.out.println("Expediente (long): " + expediente);

        // La letra de control: el resto entre 23, como la del DNI
        String letras = "TRWAGMYFPDXBNJZSQVHLCKE";
        int resto = (int) (expediente % 23);                 // long % int = long → cast a int
        char control = letras.charAt(resto);
        System.out.println("Resto entre 23: " + resto + " → letra " + control);
        System.out.println("Carné:       " + expediente + "-" + control);

        // ¿Es el usuario que tiene la secretaría?
        String usuarioSecretaria = "lsantana";
        System.out.println("usuario == \"lsantana\"      " + (usuario == usuarioSecretaria));
        System.out.println("usuario.equals(\"lsantana\") " + usuario.equals(usuarioSecretaria));
    }
}

Salida

Usuario:     lsantana
Correo:      lsantana@alu.ulpgc.es
Expediente (int):  -1214832159
Expediente (long): 20260004321
Resto entre 23: 2 → letra W
Carné:       20260004321-W
usuario == "lsantana"      false
usuario.equals("lsantana") true
Del nombre al usuario lsantanacharAt(0) da 'L', que vale 76; sumar 32 da el int 108; el cast lo convierte en 'l'; un char más un String da el String lsantana. Como se construye al ejecutar, == con el literal da false y equals da true.nombre.charAt(0)'L'76inicial + 32108int(char) (inicial + 32)'l'charinicialMin + "santana""lsantana"StringEn ASCII, 'a' – 'A' = 32: sumarlo pasa de mayúscula a minúsculausuario se construye al ejecutar → objeto nuevousuario == "lsantana" → false usuario.equals("lsantana") → true
Cada paso cambia el tipo: char, int, char y String. Fíjate en la última caja: el texto es el mismo, el objeto no.

La traza de los tipos, que es donde está la gracia de este programa:

ExpresiónTipoValor
nombre.charAt(0)char'L' (76)
inicial + 32int108
(char) (inicial + 32)char'l'
inicialMin + apellido1.toLowerCase()String"lsantana"
anioIngreso * 10000000 + numeroAlumnoint (desbordado)-1214832159
anioIngreso * 10000000L + numeroAlumnolong20260004321
expediente % 23long2
(int) (expediente % 23)int2
letras.charAt(2)char'W'

Comprobación del resto: 23 × 880869753 = 20260004319, y 20260004321 − 20260004319 = 2. La letra en la posición 2 (contando desde 0: T, R, W) es la W.

Y la última pareja de líneas es la teoría hecha realidad: usuario tiene el texto lsantana, pero se ha construido al ejecutar (a partir de variables), así que es un objeto nuevo y == con el literal da false. equals() compara las letras y da true.

Preguntas que te puedes hacer

¿Por qué inicial + 32 y no Character.toLowerCase(inicial)? En un programa de verdad usarías Character.toLowerCase, que funciona con cualquier letra (también con la Ñ). Aquí lo hacemos con la suma para ver que un char es un número. Funciona con las letras de la A a la Z.

¿Por qué el int del expediente sale negativo? 20.260.004.321 pasa del máximo de un int (2.147.483.647) y da la vuelta varias veces. El resultado es basura con forma de número. Sin ningún error.

¿Por qué (int) (expediente % 23)? expediente es long, así que el resto también es long, aunque valga 2. charAt pide un int, y pasar de long a int es un estrechamiento: hace falta el cast. Sabemos que cabe porque un resto entre 23 siempre está entre 0 y 22.

¿Y si escribo "l" + "santana" en lugar de construirlo con variables? Entonces == daría true, porque javac juntaría los dos literales al compilar (lo viste en la teoría). Es justo lo que hace peligroso a ==: funciona en la prueba rápida y falla en el programa de verdad.

¿Por qué guardar el expediente como número y no como String? Para poder calcular la letra con %. Si solo lo fueras a mostrar, un String valdría (y no tendrías problemas de tamaño).

Comprobar el usuario o la contraseña con ==. En el laboratorio, con textos que llegan del teclado, siempre dará false. equals().

La letra de control de este expediente es un invento para practicar con %; las universidades no la calculan así.

Pruébalo tú

  1. Cambia nombre por "Pablo" y apellido1 por "Medina". ¿Qué usuario sale? ¿Y si el nombre empieza por Á?
  2. Cambia numeroAlumno a 4322 y calcula la letra a mano antes de ejecutar (pista: el resto sube de uno en uno).

Errores típicos en esta práctica

  • Porcentajes enteros divididos entre 100: 25 / 100 es 0. Divide entre 100.0.
  • El cast después de la división: (double) ((a + b) / 2) llega tarde. El cast va delante de lo que se divide.
  • Cast en lugar de Math.round: (int) (total * 100) puede perder un céntimo; (int) 4.96 es un 4.
  • Calcular en int lo que no cabe: el expediente de 11 cifras necesita long y la L en la cuenta, no solo en la variable.
  • Olvidar que char + int es int: sin el cast, inicial + 32 es 108, no 'l'.
  • == con textos construidos al ejecutar: siempre equals().

Míralo paso a paso en Python Tutor

pythontutor.com ejecuta el código línea a línea y enseña el valor y el tipo de cada variable. Elige Java y pega esta versión reducida del programa 2:

public class MediaTutor {
    public static void main(String[] args) {
        int parcial1 = 7;
        int parcial2 = 8;
        int suma = parcial1 + parcial2;
        int mediaInt = suma / 2;
        double mediaTarde = (double) (suma / 2);
        double mediaBien = suma / 2.0;
        int peso = 60;
        double pesoMal = peso / 100;
        double pesoBien = peso / 100.0;
        System.out.println(mediaInt + " " + mediaTarde + " " + mediaBien);
        System.out.println(pesoMal + " " + pesoBien);
    }
}

Salida:

7 7.0 7.5
0.0 0.6

Qué observar:

  1. En int mediaInt = suma / 2; verás aparecer un 7 (no 7.5): la división entre dos int ya ha tirado el decimal.
  2. En double mediaTarde = (double) (suma / 2); aparece 7.0: el decimal está, pero vale cero. El cast llegó tarde.
  3. En double pesoMal = peso / 100; aparece 0.0. Esa variable, multiplicada por cualquier nota, es el 0.0 del compañero.
  4. Compara pesoMal y pesoBien en la última línea de la salida: 0.0 frente a 0.6, y la única diferencia del código es 100 frente a 100.0.

Resumen

  • Cada dato, una vez: variables con nombre y constantes final para lo que no cambia.
  • int / int da int. Para tener decimales, un operando double antes de dividir (/ 100.0, / 2.0 o un cast delante).
  • (int) trunca; Math.round redondea y devuelve long.
  • El dinero, en céntimos enteros: / reparte y % dice lo que sobra.
  • Si la cuenta puede pasar de 2.147.483.647, long y la L en el primer número.
  • char + int da int; los textos se comparan con equals().

Checklist: ¿lo has practicado?

  • ¿Has ejecutado los tres programas y comprobado las salidas?
  • ¿Sabrías explicar por qué el descuento mal y la nota final mal dan cero?
  • ¿Sabes repartir un importe en plazos con / y % sin perder céntimos?
  • ¿Sabes cuándo un cálculo necesita long y dónde poner la L?
  • ¿Sabes por qué usuario == "lsantana" da false?
  • ¿Has intentado los «Pruébalo tú» sin mirar la teoría?

Si has respondido que sí a casi todo, estás listo para los ejercicios de variables en Java, donde ya no te doy el código hecho. ¡Nos vemos allí!

Siguiente paso: ejerciciosVariables en Java ejercicios — IMC, segundos y el inventario de la copistería (y el porcentaje que se quedaba en 100)

¿Te ha servido este artículo? Así puedes apoyar SergioLearns →