How to convert number to words in java

前端 未结 27 3199
遇见更好的自我
遇见更好的自我 2020-11-21 23:53

We currently have a crude mechanism to convert numbers to words (e.g. using a few static arrays) and based on the size of the number translating that into an english text. B

27条回答
  •  醉梦人生
    2020-11-22 00:41

    In this post i have just update Yanick Rochon's code. I have make it workable with lower version of java 1.6 and i was getting the output for 1.00 = one and  hundredth. So i have update the code. New i get the output for 1.00 = one and zero hundredth.

    I don't not what should i do. Add a new answer or edit that post. As the answer is highly ranked so i have made a new post with updating the code. I have just change this two things have mention above.

    /**
     * This class will convert numeric values into an english representation
     * 
     * For units, see : http://www.jimloy.com/math/billion.htm
     * 
     * @author yanick.rochon@gmail.com
     */
    public class NumberToWords {
    
        static public class ScaleUnit {
            private int exponent;
            private String[] names;
    
            private ScaleUnit(int exponent, String... names) {
                this.exponent = exponent;
                this.names = names;
            }
    
            public int getExponent() {
                return exponent;
            }
    
            public String getName(int index) {
                return names[index];
            }
        }
    
        /**
         * See http://www.wordiq.com/definition/Names_of_large_numbers
         */
        static private ScaleUnit[] SCALE_UNITS = new ScaleUnit[] {
                new ScaleUnit(63, "vigintillion", "decilliard"),
                new ScaleUnit(60, "novemdecillion", "decillion"),
                new ScaleUnit(57, "octodecillion", "nonilliard"),
                new ScaleUnit(54, "septendecillion", "nonillion"),
                new ScaleUnit(51, "sexdecillion", "octilliard"),
                new ScaleUnit(48, "quindecillion", "octillion"),
                new ScaleUnit(45, "quattuordecillion", "septilliard"),
                new ScaleUnit(42, "tredecillion", "septillion"),
                new ScaleUnit(39, "duodecillion", "sextilliard"),
                new ScaleUnit(36, "undecillion", "sextillion"),
                new ScaleUnit(33, "decillion", "quintilliard"),
                new ScaleUnit(30, "nonillion", "quintillion"),
                new ScaleUnit(27, "octillion", "quadrilliard"),
                new ScaleUnit(24, "septillion", "quadrillion"),
                new ScaleUnit(21, "sextillion", "trilliard"),
                new ScaleUnit(18, "quintillion", "trillion"),
                new ScaleUnit(15, "quadrillion", "billiard"),
                new ScaleUnit(12, "trillion", "billion"),
                new ScaleUnit(9, "billion", "milliard"),
                new ScaleUnit(6, "million", "million"),
                new ScaleUnit(3, "thousand", "thousand"),
                new ScaleUnit(2, "hundred", "hundred"),
                // new ScaleUnit(1, "ten", "ten"),
                // new ScaleUnit(0, "one", "one"),
                new ScaleUnit(-1, "tenth", "tenth"), new ScaleUnit(-2, "hundredth", "hundredth"),
                new ScaleUnit(-3, "thousandth", "thousandth"),
                new ScaleUnit(-4, "ten-thousandth", "ten-thousandth"),
                new ScaleUnit(-5, "hundred-thousandth", "hundred-thousandth"),
                new ScaleUnit(-6, "millionth", "millionth"),
                new ScaleUnit(-7, "ten-millionth", "ten-millionth"),
                new ScaleUnit(-8, "hundred-millionth", "hundred-millionth"),
                new ScaleUnit(-9, "billionth", "milliardth"),
                new ScaleUnit(-10, "ten-billionth", "ten-milliardth"),
                new ScaleUnit(-11, "hundred-billionth", "hundred-milliardth"),
                new ScaleUnit(-12, "trillionth", "billionth"),
                new ScaleUnit(-13, "ten-trillionth", "ten-billionth"),
                new ScaleUnit(-14, "hundred-trillionth", "hundred-billionth"),
                new ScaleUnit(-15, "quadrillionth", "billiardth"),
                new ScaleUnit(-16, "ten-quadrillionth", "ten-billiardth"),
                new ScaleUnit(-17, "hundred-quadrillionth", "hundred-billiardth"),
                new ScaleUnit(-18, "quintillionth", "trillionth"),
                new ScaleUnit(-19, "ten-quintillionth", "ten-trillionth"),
                new ScaleUnit(-20, "hundred-quintillionth", "hundred-trillionth"),
                new ScaleUnit(-21, "sextillionth", "trilliardth"),
                new ScaleUnit(-22, "ten-sextillionth", "ten-trilliardth"),
                new ScaleUnit(-23, "hundred-sextillionth", "hundred-trilliardth"),
                new ScaleUnit(-24, "septillionth", "quadrillionth"),
                new ScaleUnit(-25, "ten-septillionth", "ten-quadrillionth"),
                new ScaleUnit(-26, "hundred-septillionth", "hundred-quadrillionth"), };
    
        static public enum Scale {
            SHORT, LONG;
    
            public String getName(int exponent) {
                for (ScaleUnit unit : SCALE_UNITS) {
                    if (unit.getExponent() == exponent) {
                        return unit.getName(this.ordinal());
                    }
                }
                return "";
            }
        }
    
        /**
         * Change this scale to support American and modern British value (short scale) or Traditional
         * British value (long scale)
         */
        static public Scale SCALE = Scale.SHORT;
    
        static abstract public class AbstractProcessor {
    
            static protected final String SEPARATOR = " ";
            static protected final int NO_VALUE = -1;
    
            protected List getDigits(long value) {
                ArrayList digits = new ArrayList();
                if (value == 0) {
                    digits.add(0);
                } else {
                    while (value > 0) {
                        digits.add(0, (int) value % 10);
                        value /= 10;
                    }
                }
                return digits;
            }
    
            public String getName(long value) {
                return getName(Long.toString(value));
            }
    
            public String getName(double value) {
                return getName(Double.toString(value));
            }
    
            abstract public String getName(String value);
        }
    
        static public class UnitProcessor extends AbstractProcessor {
    
            static private final String[] TOKENS = new String[] { "one", "two", "three", "four",
                    "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
                    "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
    
            @Override
            public String getName(String value) {
                StringBuilder buffer = new StringBuilder();
    
                int offset = NO_VALUE;
                int number;
                if (value.length() > 3) {
                    number = Integer.valueOf(value.substring(value.length() - 3), 10);
                } else {
                    number = Integer.valueOf(value, 10);
                }
                number %= 100;
                if (number < 10) {
                    offset = (number % 10) - 1;
                    // number /= 10;
                } else if (number < 20) {
                    offset = (number % 20) - 1;
                    // number /= 100;
                }
    
                if (offset != NO_VALUE && offset < TOKENS.length) {
                    buffer.append(TOKENS[offset]);
                }
    
                return buffer.toString();
            }
    
        }
    
        static public class TensProcessor extends AbstractProcessor {
    
            static private final String[] TOKENS = new String[] { "twenty", "thirty", "fourty",
                    "fifty", "sixty", "seventy", "eighty", "ninety" };
    
            static private final String UNION_SEPARATOR = "-";
    
            private UnitProcessor unitProcessor = new UnitProcessor();
    
            @Override
            public String getName(String value) {
                StringBuilder buffer = new StringBuilder();
                boolean tensFound = false;
    
                int number;
                if (value.length() > 3) {
                    number = Integer.valueOf(value.substring(value.length() - 3), 10);
                } else {
                    number = Integer.valueOf(value, 10);
                }
                number %= 100; // keep only two digits
                if (number >= 20) {
                    buffer.append(TOKENS[(number / 10) - 2]);
                    number %= 10;
                    tensFound = true;
                } else {
                    number %= 20;
                }
    
                if (number != 0) {
                    if (tensFound) {
                        buffer.append(UNION_SEPARATOR);
                    }
                    buffer.append(unitProcessor.getName(number));
                }
    
                return buffer.toString();
            }
        }
    
        static public class HundredProcessor extends AbstractProcessor {
    
            private int EXPONENT = 2;
    
            private UnitProcessor unitProcessor = new UnitProcessor();
            private TensProcessor tensProcessor = new TensProcessor();
    
            @Override
            public String getName(String value) {
                StringBuilder buffer = new StringBuilder();
    
                int number;
                if ("".equals(value)) {
                    number = 0;
                } else if (value.length() > 4) {
                    number = Integer.valueOf(value.substring(value.length() - 4), 10);
                } else {
                    number = Integer.valueOf(value, 10);
                }
                number %= 1000; // keep at least three digits
    
                if (number >= 100) {
                    buffer.append(unitProcessor.getName(number / 100));
                    buffer.append(SEPARATOR);
                    buffer.append(SCALE.getName(EXPONENT));
                }
    
                String tensName = tensProcessor.getName(number % 100);
    
                if (!"".equals(tensName) && (number >= 100)) {
                    buffer.append(SEPARATOR);
                }
                buffer.append(tensName);
    
                return buffer.toString();
            }
        }
    
        static public class CompositeBigProcessor extends AbstractProcessor {
    
            private HundredProcessor hundredProcessor = new HundredProcessor();
            private AbstractProcessor lowProcessor;
            private int exponent;
    
            public CompositeBigProcessor(int exponent) {
                if (exponent <= 3) {
                    lowProcessor = hundredProcessor;
                } else {
                    lowProcessor = new CompositeBigProcessor(exponent - 3);
                }
                this.exponent = exponent;
            }
    
            public String getToken() {
                return SCALE.getName(getPartDivider());
            }
    
            protected AbstractProcessor getHighProcessor() {
                return hundredProcessor;
            }
    
            protected AbstractProcessor getLowProcessor() {
                return lowProcessor;
            }
    
            public int getPartDivider() {
                return exponent;
            }
    
            @Override
            public String getName(String value) {
                StringBuilder buffer = new StringBuilder();
    
                String high, low;
                if (value.length() < getPartDivider()) {
                    high = "";
                    low = value;
                } else {
                    int index = value.length() - getPartDivider();
                    high = value.substring(0, index);
                    low = value.substring(index);
                }
    
                String highName = getHighProcessor().getName(high);
                String lowName = getLowProcessor().getName(low);
    
                if (!"".equals(highName)) {
                    buffer.append(highName);
                    buffer.append(SEPARATOR);
                    buffer.append(getToken());
    
                    if (!"".equals(lowName)) {
                        buffer.append(SEPARATOR);
                    }
                }
    
                if (!"".equals(lowName)) {
                    buffer.append(lowName);
                }
    
                return buffer.toString();
            }
        }
    
        static public class DefaultProcessor extends AbstractProcessor {
    
            static private String MINUS = "minus";
            static private String UNION_AND = "and";
    
            static private String ZERO_TOKEN = "zero";
    
            private AbstractProcessor processor = new CompositeBigProcessor(63);
    
            @Override
            public String getName(String value) {
                boolean negative = false;
                if (value.startsWith("-")) {
                    negative = true;
                    value = value.substring(1);
                }
    
                int decimals = value.indexOf(".");
                String decimalValue = null;
                if (0 <= decimals) {
                    decimalValue = value.substring(decimals + 1);
                    value = value.substring(0, decimals);
                }
    
                String name = processor.getName(value);
    
                if ("".equals(name)) {
                    name = ZERO_TOKEN;
                } else if (negative) {
                    name = MINUS.concat(SEPARATOR).concat(name);
                }
    
                if (!(null == decimalValue || "".equals(decimalValue))) {
    
                    String zeroDecimalValue = "";
                    for (int i = 0; i < decimalValue.length(); i++) {
                        zeroDecimalValue = zeroDecimalValue + "0";
                    }
                    if (decimalValue.equals(zeroDecimalValue)) {
                        name = name.concat(SEPARATOR).concat(UNION_AND).concat(SEPARATOR).concat(
                                "zero").concat(SEPARATOR).concat(
                                SCALE.getName(-decimalValue.length()));
                    } else {
                        name = name.concat(SEPARATOR).concat(UNION_AND).concat(SEPARATOR).concat(
                                processor.getName(decimalValue)).concat(SEPARATOR).concat(
                                SCALE.getName(-decimalValue.length()));
                    }
    
                }
    
                return name;
            }
    
        }
    
        static public AbstractProcessor processor;
    
        public static void main(String... args) {
    
            processor = new DefaultProcessor();
    
            long[] values = new long[] { 0, 4, 10, 12, 100, 108, 299, 1000, 1003, 2040, 45213, 100000,
                    100005, 100010, 202020, 202022, 999999, 1000000, 1000001, 10000000, 10000007,
                    99999999, Long.MAX_VALUE, Long.MIN_VALUE };
    
            String[] strValues = new String[] { "0", "1.30", "0001.00", "3.141592" };
    
            for (long val : values) {
                System.out.println(val + " = " + processor.getName(val));
            }
    
            for (String strVal : strValues) {
                System.out.println(strVal + " = " + processor.getName(strVal));
            }
    
            // generate a very big number...
            StringBuilder bigNumber = new StringBuilder();
            for (int d = 0; d < 66; d++) {
                bigNumber.append((char) ((Math.random() * 10) + '0'));
            }
            bigNumber.append(".");
            for (int d = 0; d < 26; d++) {
                bigNumber.append((char) ((Math.random() * 10) + '0'));
            }
            System.out.println(bigNumber.toString() + " = " + processor.getName(bigNumber.toString()));
        }
    }
    

    The output is

    0 = zero
    4 = four
    10 = ten
    12 = twelve
    100 = one hundred
    108 = one hundred eight
    299 = two hundred ninety-nine
    1000 = one thousand
    1003 = one thousand three
    2040 = two thousand fourty
    45213 = fourty-five thousand two hundred thirteen
    100000 = one hundred thousand
    100005 = one hundred thousand five
    100010 = one hundred thousand ten
    202020 = two hundred two thousand twenty
    202022 = two hundred two thousand twenty-two
    999999 = nine hundred ninety-nine thousand nine hundred ninety-nine
    1000000 = one million
    1000001 = one million one
    10000000 = ten million
    10000007 = ten million seven
    99999999 = ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-nine
    9223372036854775807 = nine quintillion two hundred twenty-three quadrillion three hundred seventy-two trillion thirty-six billion eight hundred fifty-four million seven hundred seventy-five thousand eight hundred seven
    -9223372036854775808 = minus nine quintillion two hundred twenty-three quadrillion three hundred seventy-two trillion thirty-six billion eight hundred fifty-four million seven hundred seventy-five thousand eight hundred eight
    0.0 = zero and zero tenth
    1.30 = one and thirty hundredth
    0001.00 = one and zero hundredth
    3.141592 = three and one hundred fourty-one thousand five hundred ninety-two millionth
    354064188376576616844741830273568537829518115677552666352927559274.76892492652888527014418647 = three hundred fifty-four vigintillion sixty-four novemdecillion one hundred eighty-eight octodecillion three hundred seventy-six septendecillion five hundred seventy-six sexdecillion six hundred sixteen quindecillion eight hundred fourty-four quattuordecillion seven hundred fourty-one tredecillion eight hundred thirty duodecillion two hundred seventy-three undecillion five hundred sixty-eight decillion five hundred thirty-seven nonillion eight hundred twenty-nine octillion five hundred eighteen septillion one hundred fifteen sextillion six hundred seventy-seven quintillion five hundred fifty-two quadrillion six hundred sixty-six trillion three hundred fifty-two billion nine hundred twenty-seven million five hundred fifty-nine thousand two hundred seventy-four and seventy-six septillion eight hundred ninety-two sextillion four hundred ninety-two quintillion six hundred fifty-two quadrillion eight hundred eighty-eight trillion five hundred twenty-seven billion fourteen million four hundred eighteen thousand six hundred fourty-seven hundred-septillionth
    

提交回复
热议问题