Sobre o sistema numeral do português
O numeral português segue uma lógica bem específica que difere do inglês de forma significativa. Diferentemente de outras línguas que constroem números compostos de maneira mais regular, o português tem regras próprias para dezenas e centenas, e é nessas regras que a maioria das pessoas trava quando precisa trabalhar com dados numéricos no idioma. A estrutura básica é simples. Números de um a vinte têm palavras distintas: um, dois, três, quatro, cinco, seis, sete, oito, nove, dez, onze, doze, treze, catorze, quinze, dezesseis, dezessete, dezoito, dezenove. A partir daí, entra o padrão das dezenas: vinte, trinta, quarenta, cinquenta, sessenta, setenta, oitenta, noventa. Depois, o sistema vira uma junção. Vinte e um, trinta e dois, cem. O e é obrigatório entre a dezena e a unidade, exceto quando se trata de centenas redondas ou múltiplos de cem.
O que todo mundo erra sobre numeral português
Eu trabalhei com localização de sistemas financeiros onde números precisavam ser formatados automaticamente em português. O problema que eu encontrei na prática foi com a escrita de números como "mil e cem". Muita gente escreve "mil cento e trinta", mas a norma culta exige "mil, cento e trinta", sem o "e" entre mil e cento. Esse detalhe passa despercebido até você ver um relatório fiscal vindo errado do banco porque o gerador de textos numéricos colocou um "e" onde não devia. Outro ponto que causa confusão é a variação entre "cem" e "cento". Cem só existe quando vem sozinho ou antes de outro número (cem reais, cem e cinquenta). Cento aparece quando vem seguido de outra centena (cento e cinquenta, cento e noventa e nove). A regra é simples, mas quem está automatizando isso esquece dela com frequência. Eu já vi bibliotecas de formatação de números falharem exatamente nesse ponto e gerarem "cem e vinte" em vez de "cento e vinte". Erro bobo, mas que quebra a saída do sistema.
👉 Clique no botão abaixo para saber mais sobre o assunto!
O tratamento para os milhões e bilhões também merece atenção. No português, usamos pontos como separadores de milhares e vírgulas como separador decimal, o inverso do padrão anglo-saxônico. Então 1.000.000,50 é um milhão e meia dúzia de décimos, não um milhão com vírgula cinqüenta. Quando você está migrando dados de um sistema americano para um brasileiro, essa diferença já causou problemas suficientes para fazer alguém reclamar nos fóruns de desenvolvimento por anos. Há ainda a questão dos ordinais. Primeiro, segundo, terceiro... até décimo. Depois vira decimal: décimo primeiro, décimo segundo. Essa transição muitas vezes é mal implementada em geradores automatizados, que tentam aplicar uma regra fixa demais e acabam produzindo construções estranhas como "decimoquarto" sem hífen, ou pior, "décimo-quarto" quando o correto seria manter a consistência com a forma cardinal modificada.
Se você precisa de uma implementação prática, a biblioteca num-word para Python tem um módulo de suporte a português que cobre a maioria dos casos normais. Para Node.js, o number-to-words com a locale pt-BR funciona razoavelmente bem, mas você vai precisar sobrescrever manualmente a lógica das centenas porque o comportamento padrão não respeita todas as nuances do português brasileiro. Para projetos que envolvem valores monetários em contexto formal, recomendo não confiar em nenhuma biblioteca pronta e escrever o seu próprio conversor, pelo menos para os intervalos de 1 a 999. O português de Portugal tem diferenças sutis em relação ao brasileiro que podem pegar quem não está atento. "Mil e cem" no Brasil se diz "mil cento" em Portugal. "Cem e cinquenta" no Brasil é "cento e cinquenta" em ambos, mas a ortografia de números como "sessenta" e "oitenta" — que muitos erroneamente escrevem como "cêssenta" ou "oitenha" — é um erro comum em documentos gerados por sistemas mal calibrados. O certo é sessenta e oitenta, com ss e dh respectively.
Se o seu objetivo é apenas converter números para texto em português sem complicações, comece testando com valores entre 1 e 1.999. Se funcionar, estenda até 999.999. Se houver erros nesse intervalo médio, o problema provavelmente está na regra de formação dos cientos e na inserção do "e", que como eu disse antes, é o ponto onde a maioria das implementações falha.