Foros aprenderaprogramar.com
Aprender a programar => Aprender a programar desde cero => Mensaje iniciado por: CoduJ en 22 de Abril 2020, 05:25
-
Buenas, espero que se encuentren bien.
Necesito ayuda para la comprensión de un código, realmente "entiendo" (nótese comillas) lo que está pasando... Pero no del todo:
//HorasTotrales es un objeto Scanner
Semanas = HorasTotales / 168;
Dias = HorasTotales%168 / 24;
Horas = HorasTotales%24;
¿Qué está pasando?, ¿por qué se usa el "%"? (¿se usa el resto para reducir valores para lo que son los días y horas? No entiendo), agradecería mucho si es que también me lo podrían explicar con detalle.
-
Este es un tema más de matemáticas que de programación.
Por cierto, el código de ejemplo no es correcto, las horas no se están calculando bien porque hace directamente módulo entre 24 sobre las horas totales. Y no es correcto.
Pero vamos a verlo poco a poco.
Supón que HorasTotales = 200
Y queremos saber a cuantas semanas, días y horas equivalen esa cantidad de horas.
Si una semana tiene 168 horas, pues es evidente que si dividimos esas HorasTotales entre 168, nos dirá a cuantas semanas equivalen
200 / 168 = 1,19
Vale, con ese resultado sabemos que 200 horas equivale a 1 semana y un poco más.
Esa parte decimal, el 0,19, no es una semana completa, pero equivale a cierta cantidad de días y de horas.
Pero, ¿como transformamos ese 0.19 en días? ¿Dividimos entre 24 porque un día tiene 24 horas?
0,19 / 24 = 0.007916
Buff... estamos obteniendo valores decimales muy pequeños que no nos dicen gran cosa.
Es evidente que el razonamiento matemático que estamos siguiendo no es el bueno.
No podemos coger la parte decimal y seguir haciendo cálculos con ella.
Lo que tenemos que coger es el "resto", que como su propio nombre indica, es lo que "resta" sin computar tras haber hecho la división, es lo que realmente ha sobrado.
Para obtener el resto se usa el operador "módulo", que en muchos lenguajes (no todos) se representa con el símbolo %.
Ojo porque puede confundirnos y pensar que estamos calculando porcentajes. Pero no es así, en Java ese operador lo que nos da es el resto.
Entonces, recapitulemos.
Si hacemos una "división entera" de HorasTotales entre 168 nos dirá las "semanas enteras" equivalentes.
En el código que has puesto no se ve, pero la variable Semanas seguramente será de tipo int. Esto fuerza a que la división sea "entera", es decir, esa variable no va a recoger la parte decimal, solo la parte entera.
Así que:
Semanas = 200 / 168 = 1
Ya tenemos calculado el valor de Semanas.
Ahora queremos calcular el valor de Dias.
Como hemos dicho, necesitamos el resto resultante de dividir entre 168, el valor que nos daba las semanas.
Para ello usamos el operador módulo:
Dias = 200 % 168 = 32
Tenemos el valor 32, pero eso es lo que ha sobrado al transformar en semanas.
Eso que sobra, ahora hay que transformarlo en días
32 / 24 = 1,33333
Similar a como ocurría antes, tenemos 1 día entero y un poco más.
Ese poco más, el 0.3333, no da para un día, pero si equivaldrá a unas horas que hay que calcular.
Así que una vez más, habrá que obtener el resto, que nos indicará las horas que han sobrado.
Es aquí donde fallaba el código que has puesto de ejemplo. Para las horas no se hace mod 24 directamente sobre las hora totales, si no sobre el resto obtenido al dividir entre 168
Recapitulación final:
Semanas = 200 / 168 = 1
Dias = 200 % 168 / 24 = 1
Horas = (200 % 168) % 24 = 8
Según esto, 200 horas equivalen a 1 semana, 1 día y 8 horas.
¿Es correcto?
Pues a ver...
1 semana = 168 horas
1 dia = 24 horas
resto = 8 horas
----------
200 horas
Esto, escrito así rápido en Java podría ser:
public class CalculaSemanas {
public static void main(String[] args) {
Scanner teclado = new Scanner(System.in);
System.out.print("Horas totales: ");
int horasTotal = teclado.nextInt();
int semanas = horasTotal / 168;
int dias = horasTotal % 168 / 24;
int horas = (horasTotal % 168) % 24;
System.out.println("\n" + horasTotal + " horas equivalen a");
System.out.println("- Semanas: " + semanas);
System.out.println("- Dias: " + dias);
System.out.println("- Horas: " + horas);
teclado.close();
}
}
Y si probamos a ejecutarlo en pantalla nos da este resultado:
Horas totales: 200
200 horas equivalen a
- Semanas: 1
- Dias: 1
- Horas: 8
Y bueno, espero haberme explicado bien.
Como digo, esto es más matemáticas que programación. Hay que entender como obtener el resto de la división y qué se puede calcular con él.
Pregunta lo que necesites. Y si alguien sabe explicarlo mejor que yo, por favor, que lo haga y todos aprendemos más.
Un saludo.
-
Este es un tema más de matemáticas que de programación.
Por cierto, el código de ejemplo no es correcto, las horas no se están calculando bien porque hace directamente módulo entre 24 sobre las horas totales. Y no es correcto.
Pero vamos a verlo poco a poco.
Supón que HorasTotales = 200
Y queremos saber a cuantas semanas, días y horas equivalen esa cantidad de horas.
Si una semana tiene 168 horas, pues es evidente que si dividimos esas HorasTotales entre 168, nos dirá a cuantas semanas equivalen
200 / 168 = 1,19
Vale, con ese resultado sabemos que 200 horas equivale a 1 semana y un poco más.
Esa parte decimal, el 0,19, no es una semana completa, pero equivale a cierta cantidad de días y de horas.
Pero, ¿como transformamos ese 0.19 en días? ¿Dividimos entre 24 porque un día tiene 24 horas?
0,19 / 24 = 0.007916
Buff... estamos obteniendo valores decimales muy pequeños que no nos dicen gran cosa.
Es evidente que el razonamiento matemático que estamos siguiendo no es el bueno.
No podemos coger la parte decimal y seguir haciendo cálculos con ella.
Lo que tenemos que coger es el "resto", que como su propio nombre indica, es lo que "resta" sin computar tras haber hecho la división, es lo que realmente ha sobrado.
Para obtener el resto se usa el operador "módulo", que en muchos lenguajes (no todos) se representa con el símbolo %.
Ojo porque puede confundirnos y pensar que estamos calculando porcentajes. Pero no es así, en Java ese operador lo que nos da es el resto.
Entonces, recapitulemos.
Si hacemos una "división entera" de HorasTotales entre 168 nos dirá las "semanas enteras" equivalentes.
En el código que has puesto no se ve, pero la variable Semanas seguramente será de tipo int. Esto fuerza a que la división sea "entera", es decir, esa variable no va a recoger la parte decimal, solo la parte entera.
Así que:
Semanas = 200 / 168 = 1
Ya tenemos calculado el valor de Semanas.
Ahora queremos calcular el valor de Dias.
Como hemos dicho, necesitamos el resto resultante de dividir entre 168, el valor que nos daba las semanas.
Para ello usamos el operador módulo:
Dias = 200 % 168 = 32
Tenemos el valor 32, pero eso es lo que ha sobrado al transformar en semanas.
Eso que sobra, ahora hay que transformarlo en días
32 / 24 = 1,33333
Similar a como ocurría antes, tenemos 1 día entero y un poco más.
Ese poco más, el 0.3333, no da para un día, pero si equivaldrá a unas horas que hay que calcular.
Así que una vez más, habrá que obtener el resto, que nos indicará las horas que han sobrado.
Es aquí donde fallaba el código que has puesto de ejemplo. Para las horas no se hace mod 24 directamente sobre las hora totales, si no sobre el resto obtenido al dividir entre 168
Recapitulación final:
Semanas = 200 / 168 = 1
Dias = 200 % 168 / 24 = 1
Horas = (200 % 168) % 24 = 8
Según esto, 200 horas equivalen a 1 semana, 1 día y 8 horas.
¿Es correcto?
Pues a ver...
1 semana = 168 horas
1 dia = 24 horas
resto = 8 horas
----------
200 horas
Esto, escrito así rápido en Java podría ser:
public class CalculaSemanas {
public static void main(String[] args) {
Scanner teclado = new Scanner(System.in);
System.out.print("Horas totales: ");
int horasTotal = teclado.nextInt();
int semanas = horasTotal / 168;
int dias = horasTotal % 168 / 24;
int horas = (horasTotal % 168) % 24;
System.out.println("\n" + horasTotal + " horas equivalen a");
System.out.println("- Semanas: " + semanas);
System.out.println("- Dias: " + dias);
System.out.println("- Horas: " + horas);
teclado.close();
}
}
Y si probamos a ejecutarlo en pantalla nos da este resultado:
Horas totales: 200
200 horas equivalen a
- Semanas: 1
- Dias: 1
- Horas: 8
Y bueno, espero haberme explicado bien.
Como digo, esto es más matemáticas que programación. Hay que entender como obtener el resto de la división y qué se puede calcular con él.
Pregunta lo que necesites. Y si alguien sabe explicarlo mejor que yo, por favor, que lo haga y todos aprendemos más.
Un saludo.
Vale, creo que comprendo.
Pero creo que lo que necesito es como funciona el "%", estoy un tanto confundido, sé que este operador solo obtiene el resto de una división, ¿pero solo toma el primer resto? De hecho, mientras veía ejercicios en Java, me tope con este (un tanto similar al anterior):
import java.util.Scanner;
public class Practica_7 {
public static void main(String[] args) {
int num;
int unidades, decenas;
Scanner Entrada = new Scanner(System.in);
// esta versión muesrta 11 como diez y uno.
// es una forma de hacerlo bastante burda.
// se puede poner algunos condicionales para los números especiales: 11,12,...
// y otro condicional para mostrar "y"
System.out.print("Introduzca un número (0 a 99): ");
num=Entrada.nextInt();
unidades = num % 10;
decenas = num / 10;
switch(decenas){
case 0:
System.out.print("");
break;
case 1:
System.out.print("diez");
break;
case 2:
System.out.print("veinte");
break;
case 3:
System.out.print("treinta");
break;
case 4:
System.out.print("cuarenta");
break;
case 5:
System.out.print("cincuenta");
break;
case 6:
System.out.print("sesenta");
break;
case 7:
System.out.print("setenta");
break;
case 8:
System.out.print("ochenta");
break;
case 9:
System.out.print("noventa");
break;
}
System.out.print (" y ");
switch(unidades){
case 0:
System.out.println("");
break;
case 1:
System.out.println("uno");
break;
case 2:
System.out.println("dos");
break;
case 3:
System.out.println("tres");
break;
case 4:
System.out.println("cuatro");
break;
case 5:
System.out.println("cinco");
break;
case 6:
System.out.println("seis");
break;
case 7:
System.out.println("siete");
break;
case 8:
System.out.println("ocho");
break;
case 9:
System.out.println("nueva");
break;
}
}
}
El primer y segundo problema lo "entiendo" (nótese comillas), al igual que el "%", pero me cuesta imaginar como lo podría aplicar a muchas otras cosas, lamento las molestias.
-
El operador módulo te da el resto final.
Por ejemplo, mira la división de esta imagen:
(https://www.smartick.es/blog/wp-content/uploads/35.png)
Si en el código hacemos un 243 % 5, el resultado que nos dará sera 3
Un ejemplo muy habitual en programación para practicar el operador módulo es un programa que reciba un número y diga si es par o impar.
La forma de saber si un número es par, es dividir entre 2 y comprobar si el resto es 0.
Es decir, si tenemos el número guardado en una variable llamada num, pues preguntaríamos esto:
if (num % 2 == 0)
System.out.println("Es par");
else
System.out.println("Es impar);
De este ejemplo, podemos deducir que también podemos usarlo para saber si un número es múltiplo de otro.
De nuevo, imagina que tenemos num1 y num2. Si al dividir num1 entre num2, el resto es cero, significa que num1 es múltiplo de num2.
Mayormente, el resto es útil en aplicaciones matemáticas como por ejemplo una técnica para dividir polinomios (Teorema del residuo/resto).
Pero hay también algún que otro uso curioso.
Por ejemplo en España, los DNI/NIF para identificar a cada ciudadano consta de una cadena con un número de 8 cifras y una letra.
Esa letra no es al azar, depende del resto de ese número al dividir entre 23.
En el curso de Java se propone resolver este ejercicio (https://www.aprenderaprogramar.com/index.php?option=com_content&view=article&id=182:ejercicios-ejemplos-resueltos-con-arrays-arreglos-unidimensionales-en-java-calcular-letra-dni-cu00904c&catid=58&Itemid=180) en Java.
Esta más pensado para aprender a usar arrays, pero bueno, puedes intentarlo.
-
El operador módulo te da el resto final.
Por ejemplo, mira la división de esta imagen:
(https://www.smartick.es/blog/wp-content/uploads/35.png)
Si en el código hacemos un 243 % 5, el resultado que nos dará sera 3
Un ejemplo muy habitual en programación para practicar el operador módulo es un programa que reciba un número y diga si es par o impar.
La forma de saber si un número es par, es dividir entre 2 y comprobar si el resto es 0.
Es decir, si tenemos el número guardado en una variable llamada num, pues preguntaríamos esto:
if (num % 2 == 0)
System.out.println("Es par");
else
System.out.println("Es impar);
De este ejemplo, podemos deducir que también podemos usarlo para saber si un número es múltiplo de otro.
De nuevo, imagina que tenemos num1 y num2. Si al dividir num1 entre num2, el resto es cero, significa que num1 es múltiplo de num2.
Mayormente, el resto es útil en aplicaciones matemáticas como por ejemplo una técnica para dividir polinomios (Teorema del residuo/resto).
Pero hay también algún que otro uso curioso.
Por ejemplo en España, los DNI/NIF para identificar a cada ciudadano consta de una cadena con un número de 8 cifras y una letra.
Esa letra no es al azar, depende del resto de ese número al dividir entre 23.
En el curso de Java se propone resolver este ejercicio (https://www.aprenderaprogramar.com/index.php?option=com_content&view=article&id=182:ejercicios-ejemplos-resueltos-con-arrays-arreglos-unidimensionales-en-java-calcular-letra-dni-cu00904c&catid=58&Itemid=180) en Java.
Esta más pensado para aprender a usar arrays, pero bueno, puedes intentarlo.
Ah vale, ¡muchas gracias otra vez Kabuto!.