Validar numero decimal en java

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.
}

Acerca de gonzasilve
Freelance Web Developer.

18 Responses to Validar numero decimal en java

  1. YoMero says:

    estúpido efecto de tu página no me agrada

  2. Darwing says:

    Si quiero hacer operaciones con numero enteros con parte decimal, me puedes ayudar?

  3. Pingback: PHP: Validar un numero entero « .::programming notes::. Gonzalo Silverio

  4. mario says:

    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.

    • gonzasilve says:

      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.

  5. alex says:

    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

    • gonzasilve says:

      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) );
      }
      }

      • Alex says:

        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.

    • gonzasilve says:

      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) ) );
      }

      }

    • gonzasilve says:

      …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::.

      • alez says:

        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..

    • gonzasilve says:

      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. ¿?

      • alez says:

        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

  6. Papablopo says:

    y si tiene la configuracion regional como separador de decimales una «,»

Deja un comentario