Fazer um recibo ou cheque de pagamento com o valor por extenso, emitir uma nota fiscal de venda apresentando o total do documento por extenso, são alguns exemplos de situações que sugerem a necessidade de uma aplicação comercial para definir um valor monetário em reais por extenso.

A aplicação Java implementada na Listagem 1 apresenta o método valorPorExtenso que recebe como parâmetro uma variável double que representa um valor monetário e retorna como resposta uma String com este valor por extenso:


public static String valorPorExtenso (double vlr) { ... }
import java.util.InputMismatchException;
import java.util.Scanner;

public class Um {

  public static void main(String[] args) {
    Scanner ler = new Scanner(System.in);

    double vlr;
    System.out.printf("Informe um valor em R$: ");
    try {
      vlr = ler.nextDouble();
      System.out.printf("\nValor por extenso:\n");
      System.out.printf("%s\n", valorPorExtenso(vlr));
    } catch (InputMismatchException e) {
        System.out.printf("\nErro: valor informado incompatível.\n");
    }
  }

  public static String valorPorExtenso(double vlr) {
    if (vlr == 0)
       return("zero");

    long inteiro = (long)Math.abs(vlr); // parte inteira do valor
    double resto = vlr - inteiro;       // parte fracionária do valor

    String vlrS = String.valueOf(inteiro);
    if (vlrS.length() > 15)
       return("Erro: valor superior a 999 trilhões.");

    String s = "", saux, vlrP;
    String centavos = String.valueOf((int)Math.round(resto * 100));

    String[] unidade = {"", "um", "dois", "três", "quatro", "cinco",
             "seis", "sete", "oito", "nove", "dez", "onze",
             "doze", "treze", "quatorze", "quinze", "dezesseis",
             "dezessete", "dezoito", "dezenove"};
    String[] centena = {"", "cento", "duzentos", "trezentos",
             "quatrocentos", "quinhentos", "seiscentos",
             "setecentos", "oitocentos", "novecentos"};
    String[] dezena = {"", "", "vinte", "trinta", "quarenta", "cinquenta",
             "sessenta", "setenta", "oitenta", "noventa"};
    String[] qualificaS = {"", "mil", "milhão", "bilhão", "trilhão"};
    String[] qualificaP = {"", "mil", "milhões", "bilhões", "trilhões"};

// definindo o extenso da parte inteira do valor
    int n, unid, dez, cent, tam, i = 0;
    boolean umReal = false, tem = false;
    while (!vlrS.equals("0")) {
      tam = vlrS.length();
// retira do valor a 1a. parte, 2a. parte, por exemplo, para 123456789:
// 1a. parte = 789 (centena)
// 2a. parte = 456 (mil)
// 3a. parte = 123 (milhões)
      if (tam > 3) {
         vlrP = vlrS.substring(tam-3, tam);
         vlrS = vlrS.substring(0, tam-3);
      }
      else { // última parte do valor
        vlrP = vlrS;
        vlrS = "0";
      }
      if (!vlrP.equals("000")) {
         saux = "";
         if (vlrP.equals("100"))
            saux = "cem";
         else {
           n = Integer.parseInt(vlrP, 10);  // para n = 371, tem-se:
           cent = n / 100;                  // cent = 3 (centena trezentos)
           dez = (n % 100) / 10;            // dez  = 7 (dezena setenta)
           unid = (n % 100) % 10;           // unid = 1 (unidade um)
           if (cent != 0)
              saux = centena[cent];
           if ((n % 100) <= 19) {
              if (saux.length() != 0)
                 saux = saux + " e " + unidade[n % 100];
              else saux = unidade[n % 100];
           }
           else {
              if (saux.length() != 0)
                 saux = saux + " e " + dezena[dez];
              else saux = dezena[dez];
              if (unid != 0) {
                 if (saux.length() != 0)
                    saux = saux + " e " + unidade[unid];
                 else saux = unidade[unid];
              }
           }
         }
         if (vlrP.equals("1") || vlrP.equals("001")) {
            if (i == 0) // 1a. parte do valor (um real)
               umReal = true;
            else saux = saux + " " + qualificaS[i];
         }
         else if (i != 0)
                 saux = saux + " " + qualificaP[i];
         if (s.length() != 0)
            s = saux + ", " + s;
         else s = saux;
      }
      if (((i == 0) || (i == 1)) && s.length() != 0)
         tem = true; // tem centena ou mil no valor
      i = i + 1; // próximo qualificador: 1- mil, 2- milhão, 3- bilhão, ...
    }

    if (s.length() != 0) {
       if (umReal)
          s = s + " real";
       else if (tem)
               s = s + " reais";
            else s = s + " de reais";
    }

// definindo o extenso dos centavos do valor
    if (!centavos.equals("0")) { // valor com centavos
       if (s.length() != 0) // se não é valor somente com centavos
          s = s + " e ";
       if (centavos.equals("1"))
          s = s + "um centavo";
       else {
         n = Integer.parseInt(centavos, 10);
         if (n <= 19)
            s = s + unidade[n];
         else {             // para n = 37, tem-se:
           unid = n % 10;   // unid = 37 % 10 = 7 (unidade sete)
           dez = n / 10;    // dez  = 37 / 10 = 3 (dezena trinta)
           s = s + dezena[dez];
           if (unid != 0)
              s = s + " e " + unidade[unid];
         }
         s = s + " centavos";
       }
    }
    return(s);
  }
}
Listagem 1. Aplicação Java para definir um valor por extenso

O algoritmo para resolver o problema do "valor por extenso" acaba de alguma forma apresentando uma solução complexa uma vez que várias situações devem ser previstas, por exemplo:

  1. qualificadores do valor no singular (qualificaS) e no plural (qualificaP): milhão e milhões, bilhão e bilhões;
  2. valores com tratamento diferenciado: um real, cinco reais, cem mil reais, cento e cinco milhões de reais;
  3. extenso da parte inteira do valor e da parte fracionária definidos separadamente;
  4. limitação do valor monetário de entrada a 999 trilhões.

Alguns aspectos da programação utilizada na aplicação da Listagem 1 foram abordados em outros post, citando:

  1. inicialização de vetores com valores predefinidos: Trabalhando com vetores: Vetores em Java - Parte 2;
  2. o que são String em Java: Trabalhando com string: String em Java - Parte 1;
  3. o que são String em Java: Métodos da Classe String: String em Java - Parte 2.

Ilustrando a execução da aplicação da Listagem 1:

execução da Listagem 1
execução da Listagem 1
execução da Listagem 1
execução da Listagem 1