Documentos de Académico
Documentos de Profesional
Documentos de Cultura
com
http://latecladeescape.com/algoritmos/1146-algoritmo-para-determinar-si-un-ano-es-bisiesto
El fundamento
Es importante tener claro que este algoritmo funciona para fechas del calendario gregoriano... y qu es eso? Bueno... el sistema para medir las fechas civiles que utilizamos en occidente en la actualidad. Es necesario saber que aunque es un sistema muy extendido, no es el nico que existe ahora mismo. El calendario gregoriano fue adoptado por distintos paises en distintos momentos. En Espaa se impuso en 1582, pero algunos paises, como Turqua, Grecia o Rusia lo adoptaron ya en pleno siglo XX. [important title="A modo de resumen"] Podemos decir que se aade un da ms (el 29 de Febrero) al calendario del ao correspondiente si: Regla general: el ao es divisible por cuatro.
Con la siguiente excepcin: Si el ao es divisible por 100 y no por 400 no ser bisiesto, aunque le corresponda por la regla general. [/important] Al principio puede parecer un poco lioso, pero es ms fcil de lo que parece. Basta comprobar si un ao es divisible por 4... en ese caso, debera ser bisiesto... pero tambin hay que comprobar la excepcin: si es divisible por 100 y no por 400 no lo ser. Para saber si un ao es divisible por 4, basta con aplicar el operado mdulo: "%" en C, C#, Java y compaa o "mod" en Pascal, Delphi y similares. Se trata de un operador binario (que admite dos operandos) e infijo (que se coloca entre ambos operandos) y que devuelve el resto de la divisin entera entre el primer y el segundo operando. As pues, podemos elaborar un pequeo fragmento de cdigo (En C#, como siempre) para comprobarlo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
bool EsBisiesto(int anno) { bool resultado; //Comprobamos la regla general. //Si anno es divisible por 4, es decir, si el //resto de la divisin entre 4 es 0... if (anno % 4 == 0) { //Si es divisible por 4, ahora toca comprobar //la excepcin if ( (anno % 100 == 0) && //Si es divisible por 100 (anno % 400 != 0) //y no por 400 ) { resultado = false; //entonces no es bisiesto } else { resultado = true; //No cumple la excepcin. //Lo dejamos como bisiesto por ser divisible por 4 } } else //Si no cumple la regla general { //No es bisiesto. resultado = false; } return resultado; } //EsBisiesto
Bufff... Bueno... seguramente funcionar... pero vaya rollo para comprobar tres simples condiciones. Menos mal que sabemos un montn de lgica y lo podemos dejar mucho ms sencillo, con una simple expresin booleana:
1 2 3 4 5 6 7
bool EsBisiesto(int anno) { //devuelve true si el ao es mltiplo de 4 y //no es multiplo de 100 pero no de 400 //false en caso contrario return (anno % 4 == 0) && !(anno % 100 == 0 && anno % 400 != 0); }
Quiz te ests preguntando qu es mejor... si utilizar un "if" o una expresin booleana... Bueno. La respuesta no es sencilla. El "if" conduce a un cdigo ms largo y quiz ms complicado de entender (pero no para todo el mundo... quiz alguien lo prefiera). La expresin booleana, en principio, podra parecer ms ineficiente, dado que parece que es necesario hacer varias operaciones para comprobar si el ao es bisiesto, y en la solucin con "if" si falla la regla general no se sigue comprobando ms. Sin embargo, la mayor parte de compiladores e intrpretes modernos evalan las expresiones booleanas aplicando una optimizacin conocida como Evaluacin de expresiones lgicas booleanas en cortocircuito, con lo cual, tampoco evaluaran todas las condiciones si falla la primera. Adems de todo esto... quiz hayas visto expresiones distintas a sta para comprobar si un ao es bisiesto (por ejemplo, en la Wikipedia) En realidad, se trata de la misma expresin... solo que utiliza otras operaciones. El lgebra booleana, al igual que el lgebra con nmeros tiene sus propiedades (asociativa, conmutativa, identidad... ) y algunas curiosas vueltas de tuerca (como las Leyes de Morgan) que hacen que distintas expresiones sean, en realidad, equivalentes. Por ejemplo:
1 2 3 4
bool EsBisiesto(int anno) { return ((anno % 4 == 0 && anno % 100 != 0) || anno % 400 == 0); }
Finalmente, es todo ms sencillo de lo que parece ;-D < Previo Siguiente >