Ha veces es necesario validar si una cadena es decimal o no, por ejemplo cuando el usuario de un programa debe introducir un precio, o el peso de un producto, etc. El metodo que muestro a continuacion valida si una cadena que le llega es un numero decimal devolviendo true en caso de que si y false en caso de que no.
//Devuelve true si la cadena que llega es un numero decimal, false en caso contrario
public boolean esDecimal(String cad)
{
try
{
Double.parseDouble(cad);
return true;
}
catch(NumberFormatException nfe)
{
return false;
}
}
Basicamente lo que hace este metodo es intentar convertir la cadena que llega a Decimal con el metodo parseDouble() de la clase Double (este metodo devuelve un dato de tipo double de la cadena que se le pasa como argumento) , si la conversion se puede realiza entonces el metodo devuelve true indicando que si es un numero decimal; por el contrario si la cadena que se intenta convertir a decimal no tiene la sintaxis correcta de un numero decimal, es decir, esta linea:
Double.parseDouble(cad);
lanza un excepcion del tipo NumberFormatException, entonces el metodo se va al catch y devuelve false para indicar que no es un numero decimal. Por otro lado podemos ver que incluso si a la cadena le llega un entero, por ejemplo: «544» el metodo devuelve true ( metodo parseDouble devolveria 544.0) , si nos ponemos estrictos podemos ver que 544 no es un numero decimal, ES UN NUMERO ENTERO. Entonces podemos ver que el metodo realmente lo que hace es verificar si la cadena se puede convertir a decimal, por lo tanto se deberia llamar algo asi como: esConvertibleADecimal(). Otra forma de comprobar si la cadena es un decimal es analizar caracter por caracter para detectar todos los casos en que la cadena pudiera tener un error de sintaxis. El metodo que muestro a continuacion realmente es la implementacion de un automata:
/*
Descripcion:
Contiene un metodo que Valida si una cadena es un numero decimal. Se da por hecho que a la
cadena se le han eliminado posibles espacios al principio y al final
Author: gonzasilve@gmail.com
Fecha: 08/12/2009
archivo CadenaDecimal.java
*/
public class CadenaDecimal
{
//Devuelve true si la cadena que llega tiene la sintaxis de un decimal
public boolean esDecimal(String cad)
{
boolean hayPunto=false;
StringBuffer parteEntera = new StringBuffer();
StringBuffer parteDecimal = new StringBuffer();
int i=0, posicionDelPunto;
for( i=0;i<cad.length(); i++ )
if ( cad.charAt(i) == '.') //Detectar si hay un punto decimal en la cadena
hayPunto=true;
if(hayPunto) //Si hay punto guardar la posicion donde se encuentra el carater punto
posicionDelPunto=cad.indexOf('.'); //(si la cadena tiene varios puntos, detecta donde esta el primero).
else
return false; //Si no hay punto; no es decimal
if( posicionDelPunto == cad.length()-1 || posicionDelPunto== 0) //Si el punto esta al final o al principio no es un decimal
return false;
for( i=0;i<posicionDelPunto; i++ )
parteEntera.append(cad.charAt(i)) ; //Guardar la parte entera en una variable
for(i = 0; i<parteEntera.length(); i++)
if( ! Character.isDigit(parteEntera.charAt(i)) ) //Si alguno de los caracteres de la parte entera no son digitos no es decimal
return false;
for( i=posicionDelPunto+1;i<cad.length(); i++ )
parteDecimal.append(cad.charAt(i)); //Guardar la parte decimal en una variable
for(i = 0; i<parteDecimal.length(); i++)
if( ! Character.isDigit(parteDecimal.charAt(i)) ) //Si alguno de los caracteres de la parte decimal no es un digito no es decimal
return false; //Incluye el caso en el que la cadena tenga dos o mas puntos
return true; //Si paso todas las pruebas anteriores, la cadena es un Numero decimal
}
public static void main(String args[])
{
CadenaDecimal prueba1 = new CadenaDecimal();
//Devuelve true
System.out.println("Cadena \"324.40\" es decimal: "+prueba1.esDecimal("324.40"));
//Devuelve false
System.out.println("Cadena \"324.6a\" es decimal: "+prueba1.esDecimal("324.6a"));
//Devuelve false
System.out.println("Cadena \"3a4.00\" es decimal: "+prueba1.esDecimal("3a4.00"));
//Devuelve false
System.out.println("Cadena \"3a4\" es decimal: "+prueba1.esDecimal("3a4"));
//Devuelve false, es un entero
System.out.println("Cadena \"656\" es decimal: "+prueba1.esDecimal("656"));
}
}
Este metodo es mas estricto y no acepta el «544», devuelve false pues 544 no es un decimal, ES UN ENTERO. A continuacion muestro una imagen de la compilacion y ejecucion de este metodo:
A continuacion explico un poco el codigo, esta parte:
for( i=0;i<cad.length(); i++ )
if ( cad.charAt(i) == '.') //Detectar si hay un punto decimal en la cadena
hayPunto=true;
Detecta si hay un punto dentro de la cadena, las cadenas «23.213» , «4g21.12», «.232» , «dwe.23», «434.» , «465..2ew», «.45dsd34», «87.232…» pondrian la variable hayPunto en true, pues todas estas cadenas tienen un punto.
despues el siguiente codigo:
if(hayPunto) //Si hay punto guardar la posicion donde se encuentra el carater punto
posicionDelPunto=cad.indexOf('.'); //(si la cadena tiene varios puntos, detecta donde esta el primero).
else
return false; //Si no hay punto; no es decimal
verifica si hay un punto se recoge la posicion (el indice) en donde esta esta ese punto dentro de la cadena. Si no hay punto entonces se devuelve false para indicar que la cadena no es un decimal, pues todos los numeros decimales tienen un punto decimal ¿ o no?.
despues el siguiente codigo:
if( posicionDelPunto == cad.length()-1 || posicionDelPunto== 0) //Si el punto esta al final o al principio no es un decimal
return false;
verifica si el punto esta al final o (||) si el punto esta al principio devuelve false, pues los numeros decimales no tiene el punto decimal al principio, en este caso somos muy estrictos y no se aceptan cadenas como «.547» (lleva implicito un cero como parte entera), el metodo devolveria false, por que no se acepta que el usuario piense que el sistema le va a colocar el cero como parte entera. Todo lo demas ya esta explicado en el codigo, asi que ya no lo explico mucho.
Lo siguiente es comprobar si la parte entera (los caracteres que estan antes del punto) todos son digitos enteros, si alguno no lo es entonces devolver false para indicar que no es un decimal, «67sa5.76» no es un decimal ¿o si?.
for( i=0;i<posicionDelPunto; i++ )
parteEntera.append(cad.charAt(i)) ; //Guardar la parte entera en una variable
for(i = 0; i<parteEntera.length(); i++)
if( ! Character.isDigit(parteEntera.charAt(i)) ) //Si alguno de los caracteres de la parte entera no son digitos no es decimal
return false;
El codigo anterior es el mismo que se uso en la implementacion del metodo para validar numero entero.
Lo siguiente es comprobar si la parte decimal (los caracteres que estan despues del punto) todos son digitos enteros, si alguno no lo es entonces devolver false para indicar que no es un decimal, «6757.8766», «6757..8766» no son decimales ¿o si?.
for( i=posicionDelPunto+1;i<cad.length(); i++ )
parteDecimal.append(cad.charAt(i)); //Guardar la parte decimal en una variable
for(i = 0; i<parteDecimal.length(); i++)
if( ! Character.isDigit(parteDecimal.charAt(i)) ) //Si alguno de los caracteres de la parte decimal no es un digito no es decimal
return false; //Incluye el caso en el que la cadena tenga dos o mas puntos
por ultimo se devuelve un true si la cadena pudo pasar por toda las serie de pruebas anteriores. SI las paso es por que la cadena tiene toda la sintaxis de un numero decimal correctamente escrito.
return true; //Si paso todas las pruebas anteriores, la cadena es un Numero decimal
… hasta pronto.
}
Comentarios recientes