This is an implementation of a number to word translator with a divide and conquered approach.
Here are some enumeration y used for the tens, suffix and units:
Enums
package numberTranslator;
import java.util.Arrays;
import java.util.Comparator;
public enum ExSpanishSufix {
ciento("s",2),
mil("",3),
millon("es",6),
billon("es",9),
trillon("es",12),
quadrillion("es",15);
private String plural;
private int exponent;
private long value;
private ExSpanishSufix(String plural, int exponent){
this.plural= plural;
this.exponent=exponent;
this.value=(long)Math.pow(10, exponent);
}
public static ExSpanishSufix[] getSorted(){
ExSpanishSufix[] values= ExSpanishSufix.values();
Arrays.sort(values,
Comparator.comparing((ExSpanishSufix hex) -> hex.getExponent()));
return values;
}
public String isPlural(long number){
return this.name()+(number>1?plural:"");
}
public int getExponent(){
return exponent;
}
public long getValue(){
return value;
}
}
package numberTranslator;
import java.util.Arrays;
import java.util.Comparator;
public enum SpanishDigits {
cero(0), uno(1),dos(2),tres(3),cuatro(4),cinco(5),seis(6),siete(7),ocho(8),
nueve(9), dies(10), once(11), doce(12), trece(13), catorce(14), quince(15);
private int number;
private SpanishDigits(int pnumber){
number=pnumber;
}
public static SpanishDigits[] getSorted(){
SpanishDigits[] values= SpanishDigits.values();
Arrays.sort(values,
Comparator.comparing((SpanishDigits hex) -> hex.getNumber()));
return values;
}
public int getNumber(){
return number;
}
}
package numberTranslator;
import java.util.Arrays;
import java.util.Comparator;
public enum SpanishTens {
dies(10,"dieci"), veinte(20,"veinti"), treinta(30), cuarenta(40),
cincuenta(50), sesenta(60), setenta(70), ochenta(80),
noventa(90), cien(100);
private int number;
private String plural;
private SpanishTens(int pnumber, String pplural){
number= pnumber;
plural=pplural;
}
private SpanishTens(int pnumber){
this(pnumber,"");
}
public String isPlural(int pnumber){
if(pnumber>number && plural!="")
return plural;
return name();
}
public static SpanishTens[] getSorted(){
SpanishTens[] values= SpanishTens.values();
Arrays.sort(values,
Comparator.comparing((SpanishTens des) -> des.getNumber()));
return values;
}
public int getNumber(){
return number;
}
}
Interface
package numberTranslator;
public interface ILangNumber {
public ILangNumber add(ILangNumber number);
public ILangNumber multiply(ILangNumber number);
public ILangNumber divide(ILangNumber number);
public ILangNumber pow(ILangNumber exponent);
public long getNumber();
}
package numberTranslator;
public abstract class AbstractLangNumber implements ILangNumber {
private long number;
private String parseNumber;
public AbstractLangNumber(long number){
this.number=number;
parseNumber=parseNumber(number);
}
@Override
public ILangNumber add(ILangNumber number) {
long add= getNumber()+ number.getNumber();
return createNumber(add);
}
@Override
public ILangNumber multiply(ILangNumber number) {
long mult= getNumber()*number.getNumber();
return createNumber(mult);
}
@Override
public ILangNumber divide(ILangNumber number) {
long divide= getNumber()/number.getNumber();
return createNumber(divide);
}
@Override
public ILangNumber pow(ILangNumber exponent) {
long pow= (long)Math.pow(getNumber(), exponent.getNumber());
return createNumber(pow);
}
@Override
public long getNumber() {
return number;
}
abstract protected String parseNumber(long number);
abstract protected ILangNumber createNumber(long number);
@Override
public String toString(){
return parseNumber;
}
}
Implementation
package numberTranslator;
public class SpanishNumber extends AbstractLangNumber{
public static SpanishDigits[] digits= SpanishDigits.getSorted();
public static SpanishTens[] tens= SpanishTens.getSorted();
public static ExSpanishSufix[] exponents= ExSpanishSufix.getSorted();
public SpanishNumber(long number) {
super(number);
}
@Override
protected String parseNumber(long number) {
if(number == Long.MIN_VALUE)
throw new IllegalArgumentException();
StringBuilder sb= new StringBuilder();
sb.append(getSing(number));
format(Math.abs(number),sb);
return especialCases(sb.toString());
}
@Override
protected ILangNumber createNumber(long number) {
return new SpanishNumber(number);
}
private void format( long number, StringBuilder sb){
if(number<=100)
baseCase((int)number, sb);
else
{
ExSpanishSufix suf= findSufix(number);
long leading= number/suf.getValue();
if(leading > 1)
format(leading, sb);
sb.append((suf.getExponent() == 2 ? "" : " "))
.append(suf.isPlural(leading)).append(" ");
format( number % suf.getValue(), sb);
}
}
private String especialCases(String numero){
if(numero.isEmpty())
return "cero";
return numero.replaceAll("cincocientos", "quinientos")
.replaceAll("nuevecientos", "novecientos")
.replaceAll("sietecientos", "setecientos");
}
private void baseCase(int magnitud, StringBuilder sb) {
if(magnitud<16)
sb.append(magnitud>0?digits[magnitud].name():"");
else
{
sb.append(tens[(magnitud/10)-1].isPlural(magnitud));
getUnits(magnitud,digits,sb);
}
}
private ExSpanishSufix findSufix(long number)
{
long expon= nearestPowerOf10(number);
int suf=0;
while(suf<exponents.length-1 && expon>=exponents[suf+1].getExponent())
++suf;
return exponents[suf];
}
private String getSing(long numero){
return numero<0?"menos ":"";
}
private void getUnits(int numero, SpanishDigits[] digits, StringBuilder sb){
int residuo=numero%10;
if(residuo!=0)
{
String divisor= numero>30?" y ":"";
sb.append(divisor).append(digits[residuo]);
}
}
private int nearestPowerOf10(long number){
int n = 0;
long f[]={10000000000000000L,100000000,10000,100,10};
for(int i =0, j=16; i<f.length; i++, j/=2)
{
if(number>=f[i])
{
number/=f[i];
n+=j;
}
}
return n;
}
}