Validar numero decimal en java
8 diciembre 2009 18 comentarios
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.
}
Gracis
Me salvo el semestre el Double.parseDouble 😀
estúpido efecto de tu página no me agrada
Si quiero hacer operaciones con numero enteros con parte decimal, me puedes ayudar?
..por el momento no. Saludos
Pingback: PHP: Validar un numero entero « .::programming notes::. Gonzalo Silverio
Buenos dias en caso de que quisiera crear un reconocedor de gramaticas en java, es decir, un porgrama que me reconozca operaciones aritmeticas como se podria hacer, por ejemplo que me permita escribir a+r*r/d, 1+2/5 ,2*(2/5)-3 , y haci como se prodria realizar.
Hola! Mira en este libro:
Manual de referencia C
4ta Edicion de Herbert Schildt
Editorial Osborne McGraw-Hill
viene un ejemplo pero en C, lo que tu quieres se llama ANALIZADOR DE EXPRESIONES. Espero que ese ejemplo te sirva. Saludos.
bueno, y si yo quiero que me arroje true cuando dígito un numero entero, que hay que hacer? que hay que cambiar? por ejemplo que el numero «345» arroje como resultado true.
gracias
public class ValidarEntero {
private static boolean esEntero(String num)
{
boolean esEntero = true;
for(int i=0; i<num.length(); i++)
{
if(! Character.isDigit(num.charAt(i)) )
esEntero = false;
}
return esEntero;
}
public static void main (String[] args)
{
String num = new String("345");
System.out.println("El numero "+num+" es entero: "+esEntero(num) );
}
}
muy bien y si quisiera ponerle otras restriciones como por ejemplo que no me acepte numeros negativos, obiamente que me siga aceptanto numeros enteros y decimales, y si es una cadena de letras que me saque falso.
muchas gracias de antemano.
pues usas las clases que puse arriba. Amm te falta imaginacion amigo, para ser un buen programador debes tener muucha. Bueno aqui te pongo la solucion.
public class ValidaNumeros {
public static boolean esDecimal(String cad)
{
try
{
Double.parseDouble(cad);
return true;
}
catch(NumberFormatException nfe)
{
return false;
}
}
private static boolean esEntero(String num)
{
boolean esEntero = true;
for(int i=0; i<num.length(); i++)
{
if(! Character.isDigit(num.charAt(i)) )
esEntero = false;
}
return esEntero;
}
private static boolean esNumero(String num)
{
boolean esNum = false;
if( esDecimal(num) || esEntero(num) ) {
esNum = true;
}
return esNum;
}
public static void main (String[] args)
{
String num = new String("hola");
System.out.println(" "+num+" es numero: "+esNumero(String.valueOf(num)) );
System.out.println("123 es numero: "+esNumero(String.valueOf(123) ) );
System.out.println("12.3 es numero: "+esNumero(String.valueOf(12.3) ) );
}
}
…ha y se me olvidaba para ignorar los negativos, pon dentro del metodo esNumero() para k busque el signo -, si lo tiene es que es negativo. La clase indexOf devuelve -1 cuando no encuentra el caracter buscado dentro de la cadena, de lo contrario devuelve la posicion donde esta dentro del String. El metodo esEntero() debe quedar asi:
private static boolean esNumero(String num)
{
boolean esNum = false;
if( esDecimal(num) || esEntero(num) ) {
esNum = true;
if( num.indexOf(‘-‘) >=0 )
esNum = false;
}
return esNum;
}
Saludosssss
.::CORREGIDO::.
esa validacion del numero negativo no da sale un error de caracter (ud dice que es en el metodo esEntero pero en el codigo lo ud lo hace en el metodo esNumeto), ademas haciendo la prueba se supene que el punto (.) es un decimal cuando uno digita (.) debe arrojar true y no lo hace, eso como se podria soluciona
gracias..
Amm si cometi un error de dedo, quise decir en el metodo esNumero() (y supongo que tu tbn porque escribiste ‘esNumeto’) Y SI FUNCIONA, claro que si. Lo copiaste mal tal vez, revisa
…y EL PUNTO POR SI SOLO NO ES UN DECIMAL. ¿?
ok muchas gracias pero en caso de que quisiera que el punto por si solo me arrojara true
como podria hacerlo, todo lo demas me da pero tengo esa duda ya que he tratado de hacerla y no me da.
gracias
y si tiene la configuracion regional como separador de decimales una «,»
mmm SI TIENE comas, NO LOS VALIDA, es decir el metodo esDecimal() siempre devolveria false