Here I am to ask something weird.
I would like to ask that is there any method/logic by which we can convert an integer value to a string value containing the English words for the number?
E.g user inputs 22 and gets the output twenty two or two.
Thanks
Check out this code, it might be what you're looking for. For example, inside the main method if we had:
System.out.println(convert(22));
Output:
twenty two
EDIT I've reproduced the code below, cleaning up the formatting a bit (main-method is at the bottom):
import java.text.DecimalFormat;
public class EnglishNumberToWords {
private static final String[] tensNames = { "", " ten", " twenty",
" thirty", " forty", " fifty", " sixty", " seventy", " eighty",
" ninety" };
private static final String[] numNames = { "", " one", " two", " three",
" four", " five", " six", " seven", " eight", " nine", " ten",
" eleven", " twelve", " thirteen", " fourteen", " fifteen",
" sixteen", " seventeen", " eighteen", " nineteen" };
private static String convertLessThanOneThousand(int number) {
String soFar;
if (number % 100 < 20) {
soFar = numNames[number % 100];
number /= 100;
} else {
soFar = numNames[number % 10];
number /= 10;
soFar = tensNames[number % 10] + soFar;
number /= 10;
}
if (number == 0)
return soFar;
return numNames[number] + " hundred" + soFar;
}
public static String convert(long number) {
// 0 to 999 999 999 999
if (number == 0) {
return "zero";
}
String snumber = Long.toString(number);
// pad with "0"
String mask = "000000000000";
DecimalFormat df = new DecimalFormat(mask);
snumber = df.format(number);
// XXXnnnnnnnnn
int billions = Integer.parseInt(snumber.substring(0, 3));
// nnnXXXnnnnnn
int millions = Integer.parseInt(snumber.substring(3, 6));
// nnnnnnXXXnnn
int hundredThousands = Integer.parseInt(snumber.substring(6, 9));
// nnnnnnnnnXXX
int thousands = Integer.parseInt(snumber.substring(9, 12));
String tradBillions;
switch (billions) {
case 0:
tradBillions = "";
break;
case 1:
tradBillions = convertLessThanOneThousand(billions) + " billion ";
break;
default:
tradBillions = convertLessThanOneThousand(billions) + " billion ";
}
String result = tradBillions;
String tradMillions;
switch (millions) {
case 0:
tradMillions = "";
break;
case 1:
tradMillions = convertLessThanOneThousand(millions) + " million ";
break;
default:
tradMillions = convertLessThanOneThousand(millions) + " million ";
}
result = result + tradMillions;
String tradHundredThousands;
switch (hundredThousands) {
case 0:
tradHundredThousands = "";
break;
case 1:
tradHundredThousands = "one thousand ";
break;
default:
tradHundredThousands = convertLessThanOneThousand(hundredThousands)
+ " thousand ";
}
result = result + tradHundredThousands;
String tradThousand;
tradThousand = convertLessThanOneThousand(thousands);
result = result + tradThousand;
// remove extra spaces!
return result.replaceAll("^\\s+", "").replaceAll("\\b\\s{2,}\\b", " ");
}
public static void main(String[] args) {
System.out.println(convert(22)); // "twenty two"
}
}
While the accepted answer works, it would probably be best to use already-implemented functions to perform this. ICU4J contains a class com.ibm.icu.text.RuleBasedNumberFormat that can be used to perform this operation. It also supports languages other than English, and the reverse operation, parsing a text string to integer values.
Here is an example, assuming that we have the ICU4J dependency in the classpath:
import com.ibm.icu.text.RuleBasedNumberFormat;
import java.util.Locale;
RuleBasedNumberFormat nf = new RuleBasedNumberFormat (Locale.UK, RuleBasedNumberFormat.SPELLOUT);
nf.format(24);
// The result is "twenty-four"
I have a very simple solution that can convert whole integer range in java to hinglish notation
String h1[] = { "Zero", "One", "Two", "Three", "Four", "Five", "Six",
"Seven", "Eight", "Nine", "Ten", "Eleven", "Tweleve", "Thirteen",
"Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen",
"Nineteen" };
String h2[] = { "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy",
"Eighty", "Ninety" };
String h3[] = { "Hundred", "Thousand", "Lakh", "Crore", "Arab" };
public String parseToHinglishNotation(int num) {
String word = "";
if (num < 0) {
word += "Minus ";
num = -num;
}
if (num < 20) {
word += h1[num];
} else if (num < 100) {
int temp = num / 10 - 2;
word += h2[temp];
temp = num % 10;
if (temp > 0) {
word += " " + parseToHinglishNotation(temp);
}
} else if (num < 1000) {
int temp = num / 100;
word += parseToHinglishNotation(temp) + " " + h3[0];
temp = num % 100;
if (temp > 0) {
word += " " + parseToHinglishNotation(temp);
}
} else if (num < 100000) {
int temp = num / 1000;
word += parseToHinglishNotation(temp) + " " + h3[1];
temp = num % 1000;
if (temp > 0) {
word += " " + parseToHinglishNotation(temp);
}
} else if (num < 10000000) {
int temp = num / 100000;
word += parseToHinglishNotation(temp) + " " + h3[2];
temp = num % 100000;
if (temp > 0) {
word += " " + parseToHinglishNotation(temp);
}
} else if (num < 1000000000) {
int temp = num / 10000000;
word += parseToHinglishNotation(temp) + " " + h3[3];
temp = num % 10000000;
if (temp > 0) {
word += " " + parseToHinglishNotation(temp);
}
} else if (num <= 2147483647) {
int temp = num / 1000000000;
word += parseToHinglishNotation(temp) + " " + h3[4];
temp = num % 1000000000;
if (temp > 0) {
word += " " + parseToHinglishNotation(temp);
}
}
return word;
}
I know this post is kind of old, but I recently came up with my own solution and figured it might be worth sharing. The primary function numToWords takes any Integer between 1 and 9999 (inclusive) and outputs its corresponding English words, followed by the String of digits in parenthesis.
Example: If Integer x = 2614;, numToText(x); returns "Two Thousand Six Hundred Fourteen (2614)":
The digit-equivalent words are stored in HashMaps depending on whether they're multiples of 1 or 10 (e.g. 6 --> "Six", 60 --> "Sixty") while the teens are handled independently with a switch statement.
import java.util.HashMap;
public class Converter{
public Converter(){
hm1.put(0, "");
hm1.put(1, "One");
hm1.put(2, "Two");
hm1.put(3, "Three");
hm1.put(4, "Four");
hm1.put(5, "Five");
hm1.put(6, "Six");
hm1.put(7, "Seven");
hm1.put(8, "Eight");
hm1.put(9, "Nine");
hm10.put(0, "");
hm10.put(1, "");
hm10.put(2, "Twenty ");
hm10.put(3, "Thirty ");
hm10.put(4, "Fourty ");
hm10.put(5, "Fifty ");
hm10.put(6, "Sixty ");
hm10.put(7, "Seventy ");
hm10.put(8, "Eighty ");
hm10.put(9, "Ninety ");
}
public static String numToWords(Integer x){
// Obtain a char[] of the Integer to analyze each digit.
String s = x.toString();
char[] cArray = s.toCharArray();
// Refer to the length of the Integer as its final index.
int l = cArray.length-1;
String retStr = "";
// The loop counts backwards from the right-most digit.
for(int i = l; i >= 0; i--){
// Determine the numeric value at the left-most index, then move rightward.
// This setup is attributed to the nuances of the English language.
int j = Character.getNumericValue(cArray[l-i]);
//
if(i == 3){
retStr += hm1.get(j);
retStr += " Thousand ";
} else if(i == 2){
retStr += hm1.get(j);
retStr += " Hundred ";
} else if(i == 1){
//If the 10s digit is 1, the final word is 10 <= x <= 19.
if(j == 1){
String tens = "";
// Check the 1s digit to determine x (10 <= x <= 19)
switch(Character.getNumericValue(cArray[l])){
case 0: tens = "Ten";
break;
case 1: tens = "Eleven";
break;
case 2: tens = "Twelve";
break;
case 3: tens = "Thirteen";
break;
case 4: tens = "Fourteen";
break;
case 5: tens = "Fifteen";
break;
case 6: tens = "Sixteen";
break;
case 7: tens = "Seventeen";
break;
case 8: tens = "Eighteen";
break;
case 9: tens = "Nineteen";
break;
}
i = -1; // Ensure it's the last word by indexing out of the loop.
retStr += tens;
} else {
//If the 10s digit is 2 <= x <= 9, the 10s word is 20 <= x <= 90.
retStr += hm10.get(j);
}
} else if(i == 0){
retStr += hm1.get(j);
}
}
return retStr + " (" + x + ") ";
}
private HashMap<Integer, String> hm1 = new HashMap<Integer, String>();
private HashMap<Integer, String> hm10 = new HashMap<Integer, String>();
}
Related
public class NumberToWords2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 30001;
numberToWords(n);
}
public static String numberToWords(int n){
String temp = Integer.toString(n);
int[] myArr = new int[temp.length()];
for (int i = 0; i < temp.length(); i++)
{
myArr[i] = temp.charAt(i) - '0';
}
if(myArr.length == 1){
System.out.println(oneDigits(n));
}
else if(myArr.length == 2){
System.out.println(twoDigits(n));
}
else if(myArr.length == 3){
System.out.println(threeDigits(n));
}
else if(myArr.length == 4){
System.out.println(fourDigits(n));
}
else if(myArr.length == 5){
System.out.println(fiveDigits(n));
}
return "Invalid Input";
}
///// Methods to return the equivalent English words. Logic and "And" "Thousands" etc /////
private static String fiveDigits(int n) {
// TODO Auto-generated method stub
//Check for 20000, 30000, 40000 etc
if(n%1000 == 0){
return twoDigits(n/1000) + " Thousand";
}
//Numbers starting with 1
if(n/10000 == 1){
//Handle numbers like 10001, 10002, 70024, 80099 etc
if(n%1000 < 100){
return ones(n/1000) + " Thousand And " + twoDigits(n%1000);
}
else{
return ones(n/1000) + " Thousand " + threeDigits(n%1000);
}
}
else{
if(n%1000 < 100){
return twoDigits(n/1000) + " Thousand And " + twoDigits(n%1000);
}else{
return twoDigits(n/1000) + " Thousand " + threeDigits(n%1000);
}
}
}
private static String fourDigits(int n) {
// TODO Auto-generated method stub
//Check for 2000, 3000, 4000 etc
if(n%1000 == 0){
return ones(n/1000) + " Thousand";
}
//Handle numbers like 1001, 1002, 7024, 8099 etc
else if(n%1000 < 100){
return ones(n/1000) + " Thousand And " + twoDigits(n%1000);
}
//Normal Case
else{
return ones(n/1000) + " Thousand " + threeDigits(n%1000);
}
}
private static String threeDigits(int n) {
// TODO Auto-generated method stub
//Check for 200, 300, 400 etc
if(n%100 == 0){
return ones(n/100) + " Hundred";
}
//Normal Case
else{
return ones(n/100) + " Hundred And " + twoDigits(n%100);
}
}
private static String twoDigits(int n) {
// TODO Auto-generated method stub
//Check for 11, 12, 13, 14 etc OR Handle Single digit so can reuse code
if(n/10 == 1 || n/10 == 0)
return ones(n);
//Check for 20, 30, 40 etc. Cannot print zero at the back
else if(n%10 == 0){
return tens(n/10);
}
//Normal Case
else{
return tens(n/10) + " " + ones(n%10);
}
}
private static String oneDigits(int n) {
// TODO Auto-generated method stub
return ones(n);
}
///// Return number words only /////
private static String ones(int num){
Map<Integer, String> h = new HashMap<Integer, String>();
h.put(0 , "Zero");
h.put(1 , "One");
h.put(2 , "Two");
h.put(3 , "Three");
h.put(4 , "Four");
h.put(5 , "Five");
h.put(6 , "Six");
h.put(7 , "Seven");
h.put(8 , "Eight");
h.put(9 , "Nine");
h.put(10, "Ten");
h.put(11 , "Eleven");
h.put(12 , "Twelve");
h.put(13 , "Thirteen");
h.put(14 , "Fourteen");
h.put(15 , "Fifteen");
h.put(16 , "Sixteen");
h.put(17 , "Seventeen");
h.put(18 , "Eighteen");
h.put(19 , "Nineteen");
return h.get(num);
}
private static String tens(int num){
Map<Integer, String> h = new HashMap<Integer, String>();
h.put(2 , "Twenty");
h.put(3 , "Thirty");
h.put(4 , "Fourty");
h.put(5 , "Fifty");
h.put(6 , "Sixty");
h.put(7 , "Seventy");
h.put(8 , "Eighty");
h.put(9 , "Ninety");
return h.get(num);
}
}
Im trying to learn ways of improving my code writing using lesser and more elegant ways to do conditional if else statements. Is there any way I can improve on this code to make it much shorter and readable like professionals?
I hope it help you
int numOfDigits = n/1000;
String result = String.valueOf(numOfDigits == 1? ones(numOfDigits) : twoDigits(numOfDigits));
String resultString = result + " Thousand " + twoDigits(n%1000);
if(n%1000 < 100){
resultString = result + " Thousand And " + threeDigits(n%1000);
}
return resultString;
You can use two ternary operators to make it a single expression.
For readability, you could also store the values of n / 1000 and n % 1000 in local variable to avoid repetition.
int q = n / 1000;
int r = n % 1000;
return (q / 10 == 1 ? ones(q) : twoDigits(q)) + " Thousand "
+ (r < 100 ? "And " + twoDigits(r) : threeDigits(r));
You can get simpler code by refactoring your logic and building the result piece by piece:
String result = "";
if (n/10000 == 1) {
//Handle numbers like 10001, 10002, 70024, 80099 etc
result += ones(n/1000) + " Thousand";
} else {
result += twoDigits(n/1000) + " Thousand";
}
if (n%1000 < 100) {
result += " And " + twoDigits(n%1000);
} else {
result += " " + threeDigits(n%1000);
}
return result;
I guess you could short hand it like below.
if(n/10000 == 1 && n%1000 < 100) {
return ones(n/1000) + " Thousand And " + twoDigits(n%1000);
}else if(n%1000 < 100) {
return twoDigits(n/1000) + " Thousand And " + twoDigits(n%1000);
}else{
return twoDigits(n/1000) + " Thousand " + threeDigits(n%1000);
}
You can save the calculations, provide meaningful names and indent the code properly like below:
int nOverThousand = n / 1000;
int nPercThousand = n % 1000;
int twoDigitsTerm = twoDigits(nPercThousand);
int threeDigitsTerm = threeDigits(nPercThousand);
if(nOverThousand / 10 == 1){
//Handle numbers like 10001, 10002, 70024, 80099 etc
int term1 = ones(nOverThousand);
return (nPercThousand < 100) ?
(term1 + " Thousand And " + twoDigitsTerm) :
(term1 + " Thousand " + threeDigitsTerm);
}
else{
int term1 = twoDigits(nOverThousand);
return (nPercThousand < 100) ?
(term1 + " Thousand And " + twoDigitsTerm) :
(term1 + " Thousand " + threeDigitsTerm);
}
Note that,
Readability is retained. Meaningful names makes it more readable.
You save on computations.
The code looks compact relatively.
Don't know if you'd consider this better, but here's a suggestion: (completely untested, but you get the idea)
String baseStr;
if(n/10000 == 1) {
//Handle numbers like 10001, 10002, 70024, 80099 etc
baseStr = ones(n/1000);
} else {
baseStr = twoDigits(n/1000);
}
return baseStr + " Thousand " + ((n%1000 < 100) ? "And " twoDigits(n%1000) : + threeDigits(n%1000));
So for another project I am supposed to create a program that prompts the user for a monetary value and prints out the least number of bill and coin starting with the highest. So for example, if the user input 47.63, the output would be:
0 hundreds
2 twenties
0 tens, etc.
My problem is that when i put in a certain value (namely 186.41), I should come out with 1 Hundreds
1 Fifties
1 Twenties
1 Tens
1 Fives
1 Ones
1 Quarters
1 Dimes
1 Nickles
1 Pennies.
However, my output in the pennies says "0 pennies"
Here's my code:
public class CountingMoney {
public static BufferedReader delta = new BufferedReader(new InputStreamReader(System.in));
public static void main(String [] args) throws IOException{
run();
}
public static void run() throws IOException{
System.out.println("Please enter your monetary value");
String userinput = delta.readLine();
double input = Double.parseDouble(userinput);
int amount = (int) (input / 100);
input -= amount * 100;
System.out.println(amount+ " Hundreds");
amount = (int) (input/50);
input -= amount * 50;
System.out.println(amount + " Fifties");
amount = (int) (input/20);
input -= amount * 20;
System.out.println(amount + " Twenties");
amount = (int) (input/10);
input -= amount*10;
System.out.println(amount + " Tens");
amount = (int) (input/5);
input -= amount *5;
System.out.println(amount + " Fives");
amount = (int) (input/1);
input -= amount *1;
System.out.println(amount + " Ones");
amount = (int) (input/.25);
input -= amount * .25;
System.out.println(amount + " Quarters");
amount = (int) (input/.10);
input -= amount * .10;
System.out.println(amount + " Dimes");
amount = (int) (input/.05);
input -= amount * .05;
System.out.println(amount + " Nickles");
amount = (int) (input/.01);
input -= amount * .01;
System.out.println(amount + " Pennies");
}
}
Below java program demonstrate how to convert a number from zero to one million.
NumberToStringLiteral class :
public class NumberToStringLiteral
{
public static void main(String[] args)
{
NumberToStringLiteral numberToStringLiteral = new NumberToStringLiteral();
int number = 123456;
String stringLiteral = numberToStringLiteral.convertIntegerToStringLiteral(number);
System.out.println(stringLiteral);
}
private String convertIntegerToStringLiteral(int number)
{
if (number < 100)
return from_0_To_100(number);
if ( number >= 100 && number < 1000 )
return from_101_To_999(number);
if ( number >= 1000 && number <= 99999)
return from_1000_and_99999(number);
if (number <= 1000000)
return from_100000_and_above(number);
return Digits.OVER_ONE_MILLION.getStringLiteral();
}
private String from_0_To_100(int number)
{
if (number <= 19 )
return ZeroToNineteen.getStringLiteral(number);
String LastDigit = ( ZeroToNineteen.getStringLiteral(number % 10) != ZeroToNineteen.ZERO.getStringLiteral() ) ?
ZeroToNineteen.getStringLiteral(number % 10) : "";
return Tens.getStringLiteralFromNumber( (number - (number % 10 )) ) + " " + LastDigit;
}
private String from_101_To_999(int number)
{
String LastDigit = ( ZeroToNineteen.getStringLiteral(number % 100) != ZeroToNineteen.ZERO.getStringLiteral() ) ?
ZeroToNineteen.getStringLiteral(number % 100) : "";
if ( (number % 100) > 19)
LastDigit = from_0_To_100(number % 100);
if (LastDigit.isBlank())
return ZeroToNineteen.getStringLiteral(number / 100 ) + Digits.getStringLiteral(getNumberOfDigit(0));
return ZeroToNineteen.getStringLiteral(number / 100 ) + Digits.getStringLiteral(getNumberOfDigit(number)) + LastDigit;
}
private String from_1000_and_99999(int number)
{
String LastDigit = (number % 1000 < 20 ) ? from_0_To_100(number % 1000) : from_101_To_999(number % 1000);
if (LastDigit.equalsIgnoreCase(ZeroToNineteen.ZERO.getStringLiteral()))
LastDigit = "";
return from_0_To_100(number / 1000 ) + Digits.getStringLiteral(getNumberOfDigit(number)) + LastDigit;
}
private String from_100000_and_above(int number)
{
if (number == 1000000)
return Digits.ONE_MILLION.getStringLiteral();
String lastThreeDigit = (number % 1000 <= 100) ? from_0_To_100(number % 1000) : from_101_To_999(number % 1000);
if (lastThreeDigit.equalsIgnoreCase(ZeroToNineteen.ZERO.toString()))
lastThreeDigit = "";
String number1 = from_101_To_999(number / 1000) + Digits.THOUSAND.getStringLiteral() + lastThreeDigit;
return String.valueOf(number1);
}
private int getNumberOfDigit(int number)
{
int count = 0;
while ( number != 0 )
{
number /= 10;
count++;
}
return count;
}
}
ZeroToNineteen enum :
public enum ZeroToNineteen
{
ZERO(0, "zero"),
ONE(1, "one"),
TWO(2, "two"),
THREE(3, "three"),
FOUR(4, "four"),
FIVE(5, "five"),
SIX(6, "six"),
SEVEN(7, "seven"),
EIGHT(8, "eight"),
NINE(9, "nine"),
TEN(10, "ten"),
ELEVEN(11, "eleven"),
TWELVE(12, "twelve"),
THIRTEEN(13, "thirteen"),
FOURTEEN(14, "fourteen"),
FIFTEEN(15, "fifteen"),
SIXTEEN(16, "sixteen"),
SEVENTEEN(17, "seventeen"),
EIGHTEEN(18, "eighteen"),
NINETEEN(19, "nineteen");
private int number;
private String stringLiteral;
public static Map<Integer, String> stringLiteralMap;
ZeroToNineteen(int number, String stringLiteral)
{
this.number = number;
this.stringLiteral = stringLiteral;
}
public int getNumber()
{
return this.number;
}
public String getStringLiteral()
{
return this.stringLiteral;
}
public static String getStringLiteral(int number)
{
if (stringLiteralMap == null)
addData();
return stringLiteralMap.get(number);
}
private static void addData()
{
stringLiteralMap = new HashMap<>();
for (ZeroToNineteen zeroToNineteen : ZeroToNineteen.values())
{
stringLiteralMap.put(zeroToNineteen.getNumber(), zeroToNineteen.getStringLiteral());
}
}
}
Tens enum :
public enum Tens
{
TEN(10, "ten"),
TWENTY(20, "twenty"),
THIRTY(30, "thirty"),
FORTY(40, "forty"),
FIFTY(50, "fifty"),
SIXTY(60, "sixty"),
SEVENTY(70, "seventy"),
EIGHTY(80, "eighty"),
NINETY(90, "ninety"),
HUNDRED(100, "one hundred");
private int number;
private String stringLiteral;
private static Map<Integer, String> stringLiteralMap;
Tens(int number, String stringLiteral)
{
this.number = number;
this.stringLiteral = stringLiteral;
}
public int getNumber()
{
return this.number;
}
public String getStringLiteral()
{
return this.stringLiteral;
}
public static String getStringLiteralFromNumber(int number)
{
if (stringLiteralMap == null)
addDataToStringLiteralMap();
return stringLiteralMap.get(number);
}
private static void addDataToStringLiteralMap()
{
stringLiteralMap = new HashMap<Integer, String>();
for (Tens tens : Tens.values())
stringLiteralMap.put(tens.getNumber(), tens.getStringLiteral());
}
}
Digits enum :
public enum Digits
{
HUNDRED(3, " hundred and "),
THOUSAND(4, " thousand "),
TEN_THOUSAND(5," thousand "),
ONLY_HUNDRED(0, " hundred" ),
ONE_MILLION(1000000, "one million"),
OVER_ONE_MILLION(1000001, "over one million");
private int digit;
private String stringLiteral;
private static Map<Integer, String> stringLiteralMap;
private Digits(int digit, String stringLiteral)
{
this.digit = digit;
this.stringLiteral = stringLiteral;
}
public int getDigit()
{
return this.digit;
}
public String getStringLiteral()
{
return this.stringLiteral;
}
public static String getStringLiteral(int number)
{
if ( stringLiteralMap == null )
addStringLiteralMap();
return stringLiteralMap.get(number);
}
private static void addStringLiteralMap()
{
stringLiteralMap = new HashMap<Integer, String>();
for ( Digits digits : Digits.values() )
stringLiteralMap.put(digits.getDigit(), digits.getStringLiteral());
}
}
Output :
one hundred and twenty three thousand four hundred and fifty six
Note: I have used all three enum for constant variables, you can also use array.
Hope this will help you, Let me know if you have any doubt in comment section.
When you cast a double to an int with (int), it always rounds down, no matter how close the double value is to the integer just above it. doubles cannot represent values like 186.41 exactly, because they're stored in binary instead of decimal. When you start doing lots of calculations with them, the errors start accumulating.
When I try your program, and show the value that's being rounded:
System.out.println("result of division is " + (input/.01));
amount = (int) (input/.01);
input -= amount * .01;
System.out.println(amount + " Pennies");
it displays
result of division is 0.999999999999658
This is very, very close to 1, so not that much error has been accumulated. But it's not exact. And since casting to (int) rounds down, amount will be 0.
There are two ways to solve this:
1) Use BigDecimal as suggested in the other answer. This is the preferred method of dealing with money. It will represent decimal places exactly.
2) Use Math.round() instead of (int), e.g.
amount = (int) Math.round(input / .01);
Math.round on a double returns a long, so you still need a cast, but it's casting from an integer to another integer so no rounding is involved.
I still recommend using BigDecimal. However, this should help you see that in other situations, where you do need to deal with double, you need to pay attention to what kind of rounding you do. Casting to (int) will often be wrong, depending on what you're trying to do.
The issue you're facing is better explained over here.
To overcome this use BigDecimal. However make sure you set the Scale and RoundingMode. If not you might end up with java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. during your divide operation.
Sample Code on how to modify:
amount = bigDecimal.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).intValue();
bigDecimal = bigDecimal.subtract(new BigDecimal(amount * 100));
System.out.println(amount+ " Hundreds");
You can use below code and it is available in this link
For more reference and discussion you can refer this stack-overflow post
Hope it will solve your need.
package com.test;
import java.text.DecimalFormat;
public class EnglishNumberToWords {
private static final String[] tensNames = {
"",
" ten",
" twenty",
" thirty",
" forty",
" fifty",
" sixty",
" seventy",
" eighty",
" ninety"
};
private static final String[] numNames = {
"",
" one",
" two",
" three",
" four",
" five",
" six",
" seven",
" eight",
" nine",
" ten",
" eleven",
" twelve",
" thirteen",
" fourteen",
" fifteen",
" sixteen",
" seventeen",
" eighteen",
" nineteen"
};
private EnglishNumberToWords() {}
private static String convertLessThanOneThousand(int number) {
String soFar;
if (number % 100 < 20){
soFar = numNames[number % 100];
number /= 100;
}
else {
soFar = numNames[number % 10];
number /= 10;
soFar = tensNames[number % 10] + soFar;
number /= 10;
}
if (number == 0) {
return soFar;
}
return numNames[number] + " hundred" + soFar;
}
public static String convert(long number) {
// 0 to 999 999 999 999
if (number == 0) { return "zero"; }
String snumber = Long.toString(number);
// pad with "0"
String mask = "000000000000";
DecimalFormat df = new DecimalFormat(mask);
snumber = df.format(number);
// XXXnnnnnnnnn
int billions = Integer.parseInt(snumber.substring(0,3));
// nnnXXXnnnnnn
int millions = Integer.parseInt(snumber.substring(3,6));
// nnnnnnXXXnnn
int hundredThousands = Integer.parseInt(snumber.substring(6,9));
// nnnnnnnnnXXX
int thousands = Integer.parseInt(snumber.substring(9,12));
String tradBillions;
switch (billions) {
case 0:
tradBillions = "";
break;
case 1 :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
break;
default :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
}
String result = tradBillions;
String tradMillions;
switch (millions) {
case 0:
tradMillions = "";
break;
case 1 :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
break;
default :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
}
result = result + tradMillions;
String tradHundredThousands;
switch (hundredThousands) {
case 0:
tradHundredThousands = "";
break;
case 1 :
tradHundredThousands = "one thousand ";
break;
default :
tradHundredThousands = convertLessThanOneThousand(hundredThousands)
+ " thousand ";
}
result = result + tradHundredThousands;
String tradThousand;
tradThousand = convertLessThanOneThousand(thousands);
result = result + tradThousand;
// remove extra spaces!
return result.replaceAll("^\\s+", "").replaceAll("\\b\\s{2,}\\b", " ");
}
/**
* testing
* #param args
*/
public static void main(String[] args) {
System.out.println("*0* " + EnglishNumberToWords.convert(0));
System.out.println("*1* " + EnglishNumberToWords.convert(1));
System.out.println("*16* " + EnglishNumberToWords.convert(16));
System.out.println("*100* " + EnglishNumberToWords.convert(100));
System.out.println("*118* " + EnglishNumberToWords.convert(118));
System.out.println("*200* " + EnglishNumberToWords.convert(200));
System.out.println("*219* " + EnglishNumberToWords.convert(219));
System.out.println("*800* " + EnglishNumberToWords.convert(800));
System.out.println("*801* " + EnglishNumberToWords.convert(801));
System.out.println("*1316* " + EnglishNumberToWords.convert(1316));
System.out.println("*1316* " + EnglishNumberToWords.convert(1316));
System.out.println("*2000000* " + EnglishNumberToWords.convert(2000000));
System.out.println("*3000200* " + EnglishNumberToWords.convert(3000200));
System.out.println("*700000* " + EnglishNumberToWords.convert(700000));
System.out.println("*9000000* " + EnglishNumberToWords.convert(9000000));
System.out.println("*9001000* " + EnglishNumberToWords.convert(9001000));
System.out.println("*123456789* " + EnglishNumberToWords.convert(123456789));
System.out.println("*2147483647* " + EnglishNumberToWords.convert(2147483647));
System.out.println("*3000000010L* " + EnglishNumberToWords.convert(3000000010L));
}
}
This question already has answers here:
How to convert number to words in java
(31 answers)
Closed 8 years ago.
When this was assign to me I already had something in mind on how to do it, but that "Thing" that I was thinking is to do it manually 1-1000 like so:
import.java.io.*
public static void main(String[] args) throws IOException
{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int num;
System.out.println("Enter Numbers to convert: ");
num=Integer.parseInt(in.readLine());
if (num==1)
{
System.out.println("one");
}
else if(num==2)
{
System.out.println("two");
}
else if(num==3)
{
System.out.println("three");
}
\*and so on up to 1000*\
Please help i dont want to do that ! im just a noob programmer :(
Got it from here and modified it according to your needs. Credit goes fully to the original owner of this code.
import java.text.DecimalFormat;
public class EnglishNumberToWords {
private static final String[] tensNames = {
"",
" ten",
" twenty",
" thirty",
" forty",
" fifty",
" sixty",
" seventy",
" eighty",
" ninety"
};
private static final String[] numNames = {
"",
" one",
" two",
" three",
" four",
" five",
" six",
" seven",
" eight",
" nine",
" ten",
" eleven",
" twelve",
" thirteen",
" fourteen",
" fifteen",
" sixteen",
" seventeen",
" eighteen",
" nineteen"
};
private EnglishNumberToWords() {}
private static String convertLessThanOneThousand(int number) {
String soFar;
if (number % 100 < 20){
soFar = numNames[number % 100];
number /= 100;
}
else {
soFar = numNames[number % 10];
number /= 10;
soFar = tensNames[number % 10] + soFar;
number /= 10;
}
if (number == 0) return soFar;
return numNames[number] + " hundred" + soFar;
}
public static String convert(long number) {
// 0 to 999 999 999 999
if (number == 0) { return "zero"; }
String snumber = Long.toString(number);
// pad with "0"
String mask = "000000000000";
DecimalFormat df = new DecimalFormat(mask);
snumber = df.format(number);
// XXXnnnnnnnnn
int billions = Integer.parseInt(snumber.substring(0,3));
// nnnXXXnnnnnn
int millions = Integer.parseInt(snumber.substring(3,6));
// nnnnnnXXXnnn
int hundredThousands = Integer.parseInt(snumber.substring(6,9));
// nnnnnnnnnXXX
int thousands = Integer.parseInt(snumber.substring(9,12));
String tradBillions;
switch (billions) {
case 0:
tradBillions = "";
break;
case 1 :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
break;
default :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
}
String result = tradBillions;
String tradMillions;
switch (millions) {
case 0:
tradMillions = "";
break;
case 1 :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
break;
default :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
}
result = result + tradMillions;
String tradHundredThousands;
switch (hundredThousands) {
case 0:
tradHundredThousands = "";
break;
case 1 :
tradHundredThousands = "one thousand ";
break;
default :
tradHundredThousands = convertLessThanOneThousand(hundredThousands)
+ " thousand ";
}
result = result + tradHundredThousands;
String tradThousand;
tradThousand = convertLessThanOneThousand(thousands);
result = result + tradThousand;
// remove extra spaces!
return result.replaceAll("^\\s+", "").replaceAll("\\b\\s{2,}\\b", " ");
}
/**
* testing
* #param args
*/
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the number");
int i = scanner.nextInt();
System.out.println("*** " + EnglishNumberToWords.convert(i));
}
catch(Exception e) {
}
}
}
A more simple one :
public class ConvertNumberToWords {
final private static String[] units = {"Zero","One","Two","Three","Four",
"Five","Six","Seven","Eight","Nine","Ten",
"Eleven","Twelve","Thirteen","Fourteen","Fifteen",
"Sixteen","Seventeen","Eighteen","Nineteen"};
final private static String[] tens = {"","","Twenty","Thirty","Forty","Fifty",
"Sixty","Seventy","Eighty","Ninety"};
public static String convert(Integer i) {
if( i < 20) return units[i];
if( i < 100) return tens[i/10] + ((i % 10 > 0)? " " + convert(i % 10):"");
if( i < 1000) return units[i/100] + " Hundred" + ((i % 100 > 0)?" and " + convert(i % 100):"");
if( i < 1000000) return convert(i / 1000) + " Thousand " + ((i % 1000 > 0)? " " + convert(i % 1000):"") ;
return convert(i / 1000000) + " Million " + ((i % 1000000 > 0)? " " + convert(i % 1000000):"") ;
}
public static void main(String[]args){
for(int i=1;i<1000;i++){
System.out.println(i+" \t "+convert(i));
}
}
}
you have to made numberArray upto thousand count if you want to print string against each read number :P
public static void main(String[] args) throws IOException
{
public static final String[] numberArray = new String[] {
"one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
};
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
String number = in.readLine();
int num = 0;
while(num!=1000){
if (num == Integer.parseInt(number)) {
System.out.println(numberArray[num]);
}
num++;
}
}
Our assignment states that we write a program that will input a number up to 6 digits and will convert the numbers into words.. ex: 123 = one hundred twenty three. I AM CLUELESS! Then I found this site http://www.rgagnon.com/javadetails/java-0426.html
but I don't really understand how to convert it into android.
please help me..please.
here is my Main_Activity.xml:
package com.example.torres;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
final EditText numbers = (EditText) findViewById(R.id.editText1);
final EditText results = (EditText) findViewById(R.id.editText2);
Button btnConvert = (Button) findViewById(R.id.button1);
btnConvert.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
String numberz =numbers.getText().toString();
try {
final long number = Long.parseLong(numberz);
String returnz = Words.convert(number);
} catch ( NumberFormatException e) {
//Toast.makeToast("illegal number or empty number" , toast.long)
}
} });
}}
and here is my Words.java
package com.example.torres;
import java.text.DecimalFormat;
public class Words {
private static final String[] tensNames = {
"",
" ten",
" twenty",
" thirty",
" forty",
" fifty",
" sixty",
" seventy",
" eighty",
" ninety"
};
private static final String[] numNames = {
"",
" one",
" two",
" three",
" four",
" five",
" six",
" seven",
" eight",
" nine",
" ten",
" eleven",
" twelve",
" thirteen",
" fourteen",
" fifteen",
" sixteen",
" seventeen",
" eighteen",
" nineteen"
};
private Words() {}
public static String convertLessThanOneThousand(int number) {
String soFar;
if (number % 100 < 20){
soFar = numNames[number % 100];
number /= 100;
}
else {
soFar = numNames[number % 10];
number /= 10;
soFar = tensNames[number % 10] + soFar;
number /= 10;
}
if (number == 0) return soFar;
return numNames[number] + " hundred" + soFar;
}
public static String convert(long number) {
// 0 to 999 999 999 999
if (number == 0) { return "zero"; }
String snumber = Long.toString(number);
// pad with "0"
String mask = "000000000000";
DecimalFormat df = new DecimalFormat(mask);
snumber = df.format(number);
// XXXnnnnnnnnn
int billions = Integer.parseInt(snumber.substring(0,3));
// nnnXXXnnnnnn
int millions = Integer.parseInt(snumber.substring(3,6));
// nnnnnnXXXnnn
int hundredThousands = Integer.parseInt(snumber.substring(6,9));
// nnnnnnnnnXXX
int thousands = Integer.parseInt(snumber.substring(9,12));
String tradBillions;
switch (billions) {
case 0:
tradBillions = "";
break;
case 1 :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
break;
default :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
}
String result = tradBillions;
String tradMillions;
switch (millions) {
case 0:
tradMillions = "";
break;
case 1 :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
break;
default :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
}
result = result + tradMillions;
String tradHundredThousands;
switch (hundredThousands) {
case 0:
tradHundredThousands = "";
break;
case 1 :
tradHundredThousands = "one thousand ";
break;
default :
tradHundredThousands = convertLessThanOneThousand(hundredThousands)
+ " thousand ";
}
result = result + tradHundredThousands;
String tradThousand;
tradThousand = convertLessThanOneThousand(thousands);
result = result + tradThousand;
// remove extra spaces!
return result.replaceAll("^\\s+", "").replaceAll("\\b\\s{2,}\\b", " ");}
}
The only problem now is that nothing happens lol
You can make separate class for EnglishNumberToWords as in the example link.
and in your button click you have to just call
String return_val_in_english = EnglishNumberToWords.convert(YOUR_NUMBER_TO_CONVERT);
public class EnglishNumberToWords {
private static final String[] tensNames = { "", " ten", " twenty", " thirty", " forty",
" fifty", " sixty", " seventy", " eighty", " ninety" };
private static final String[] numNames = { "", " one", " two", " three", " four", " five",
" six", " seven", " eight", " nine", " ten", " eleven", " twelve", " thirteen",
" fourteen", " fifteen", " sixteen", " seventeen", " eighteen", " nineteen" };
private static String convertLessThanOneThousand(int number)
{
String soFar;
if (number % 100 < 20)
{
soFar = numNames[number % 100];
number /= 100;
} else
{
soFar = numNames[number % 10];
number /= 10;
soFar = tensNames[number % 10] + soFar;
number /= 10;
}
if (number == 0)
return soFar;
return numNames[number] + " hundred" + soFar;
}
public static String convert(long number)
{
// 0 to 999 999 999 999
if (number == 0)
{
return "zero";
}
String snumber = Long.toString(number);
// pad with "0"
String mask = "000000000000";
DecimalFormat df = new DecimalFormat(mask);
snumber = df.format(number);
// XXXnnnnnnnnn
int billions = Integer.parseInt(snumber.substring(0, 3));
// nnnXXXnnnnnn
int millions = Integer.parseInt(snumber.substring(3, 6));
// nnnnnnXXXnnn
int hundredThousands = Integer.parseInt(snumber.substring(6, 9));
// nnnnnnnnnXXX
int thousands = Integer.parseInt(snumber.substring(9, 12));
String tradBillions;
switch (billions)
{
case 0:
tradBillions = "";
break;
case 1:
tradBillions = convertLessThanOneThousand(billions) + " billion ";
break;
default:
tradBillions = convertLessThanOneThousand(billions) + " billion ";
}
String result = tradBillions;
String tradMillions;
switch (millions)
{
case 0:
tradMillions = "";
break;
case 1:
tradMillions = convertLessThanOneThousand(millions) + " million ";
break;
default:
tradMillions = convertLessThanOneThousand(millions) + " million ";
}
result = result + tradMillions;
String tradHundredThousands;
switch (hundredThousands)
{
case 0:
tradHundredThousands = "";
break;
case 1:
tradHundredThousands = "one thousand ";
break;
default:
tradHundredThousands = convertLessThanOneThousand(hundredThousands) + " thousand ";
}
result = result + tradHundredThousands;
String tradThousand;
tradThousand = convertLessThanOneThousand(thousands);
result = result + tradThousand;
// remove extra spaces!
return result.replaceAll("^\\s+", "").replaceAll("\\b\\s{2,}\\b", " ");
}
}
Above all the solution is working fine, Only problem is that this is not working for all language because all country is not having the same set of rules to convert a number into word so we need to write a separate algorithm for each country,
Solution
ICU4J is an international Unicode component library that is allowed so many utilities regarding language translation follow below steps.
Step 1 Add ICU4J in your app level gradle like below
dependencies {
implementation group: 'com.ibm.icu', name: 'icu4j', version: '51.1'
}
Step 2 Define this method
private String convertIntoWords(Double str,String language,String Country) {
Locale local = new Locale(language, Country);
RuleBasedNumberFormat ruleBasedNumberFormat = new RuleBasedNumberFormat(local, RuleBasedNumberFormat.SPELLOUT);
return ruleBasedNumberFormat.format(str);
}
Step 3
Now you can call this method like below
double value=165;
String english=convertIntoWords(value,"en","US"); //one hundred and sixty-five
/*Peruvion*/
String Spanish=convertIntoWords(value,"es","PE"); //ciento sesenta y cinco
You can change language and country based on your requirements.
Enjoy
Posting my answer here because can be helpful to someone else...
import android.icu.text.MessageFormat
import java.util.Locale
fun Double.toWords(language: String, country: String): String {
val formatter = MessageFormat(
"{0,spellout,currency}",
Locale(language, country)
)
return formatter.format(arrayOf(this))
}
and you can use it like this:
import androidx.compose.ui.text.intl.Locale
// ...
(12345678.99).toWords(Locale.current.language, Locale.current.region)
// OR,
(12345678.99).toWords("en", "US") // For static local
This call will return the string
twelve million three hundred forty-five thousand six hundred seventy-eight point nine nine
Reference: https://developer.android.com/reference/android/icu/text/MessageFormat
Java Class for that :-
public class NumberToWordsConverter {
public static final String[] units = {"", "One", "Two", "Three", "Four",
"Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve",
"Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen",
"Eighteen", "Nineteen"};
public static final String[] tens = {
"", // 0
"", // 1
"Twenty", // 2
"Thirty", // 3
"Forty", // 4
"Fifty", // 5
"Sixty", // 6
"Seventy", // 7
"Eighty", // 8
"Ninety" // 9
};
public static String convert(final int n) {
if (n < 0) {
return "Minus " + convert(-n);
}
if (n < 20) {
return units[n];
}
if (n < 100) {
return tens[n / 10] + ((n % 10 != 0) ? " " : "") + units[n % 10];
}
if (n < 1000) {
return units[n / 100] + " Hundred" + ((n % 100 != 0) ? " " : "") + convert(n % 100);
}
if (n < 100000) {
return convert(n / 1000) + " Thousand" + ((n % 10000 != 0) ? " " : "") + convert(n % 1000);
}
if (n < 10000000) {
return convert(n / 100000) + " Lakh" + ((n % 100000 != 0) ? " " : "") + convert(n % 100000);
}
return convert(n / 10000000) + " Crore" + ((n % 10000000 != 0) ? " " : "") + convert(n % 10000000);
}
}
Implementation in your main class.
You can have separate method like the follwing or you can directly use without separate method.
private String numToWords (int n){ //optional
NumberToWordsConverter ntw = new NumberToWordsConverter(); // directly implement this
return ntw.convert(n);
} //optional
You have done all the work just display String returnz in a text field like this
results.setText(returnz);
Anyone know of a java library that can take very large spelled numbers and convert them into digits? It'd be nice if it could do decimal places as well. Example.. Ten to 10
Hmm why not try your own? Here are 2 samples to start you off:
import java.util.*;
public class NumToWords {
String string;
String st1[] = { "", "one", "two", "three", "four", "five", "six", "seven",
"eight", "nine", };
String st2[] = { "hundred", "thousand", "lakh", "crore" };
String st3[] = { "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "ninteen", };
String st4[] = { "twenty", "thirty", "fourty", "fifty", "sixty", "seventy",
"eighty", "ninty" };
public String convert(int number) {
int n = 1;
int word;
string = "";
while (number != 0) {
switch (n) {
case 1:
word = number % 100;
pass(word);
if (number > 100 && number % 100 != 0) {
show("and ");
}
number /= 100;
break;
case 2:
word = number % 10;
if (word != 0) {
show(" ");
show(st2[0]);
show(" ");
pass(word);
}
number /= 10;
break;
case 3:
word = number % 100;
if (word != 0) {
show(" ");
show(st2[1]);
show(" ");
pass(word);
}
number /= 100;
break;
case 4:
word = number % 100;
if (word != 0) {
show(" ");
show(st2[2]);
show(" ");
pass(word);
}
number /= 100;
break;
case 5:
word = number % 100;
if (word != 0) {
show(" ");
show(st2[3]);
show(" ");
pass(word);
}
number /= 100;
break;
}
n++;
}
return string;
}
public void pass(int number) {
int word, q;
if (number < 10) {
show(st1[number]);
}
if (number > 9 && number < 20) {
show(st3[number - 10]);
}
if (number > 19) {
word = number % 10;
if (word == 0) {
q = number / 10;
show(st4[q - 2]);
} else {
q = number / 10;
show(st1[word]);
show(" ");
show(st4[q - 2]);
}
}
}
public void show(String s) {
String st;
st = string;
string = s;
string += st;
}
public static void main(String[] args) {
NumToWords w = new NumToWords();
Scanner input = new Scanner(System.in);
System.out.print("Enter Number: ");
int num = input.nextInt();
String inwords = w.convert(num);
System.out.println(inwords);
}
}
and this:
class constNumtoLetter
{
String[] unitdo ={"", " One", " Two", " Three", " Four", " Five",
" Six", " Seven", " Eight", " Nine", " Ten", " Eleven", " Twelve",
" Thirteen", " Fourteen", " Fifteen", " Sixteen", " Seventeen",
" Eighteen", " Nineteen"};
String[] tens = {"", "Ten", " Twenty", " Thirty", " Forty", " Fifty",
" Sixty", " Seventy", " Eighty"," Ninety"};
String[] digit = {"", " Hundred", " Thousand", " Lakh", " Crore"};
int r;
//Count the number of digits in the input number
int numberCount(int num)
{
int cnt=0;
while (num>0)
{
r = num%10;
cnt++;
num = num / 10;
}
return cnt;
}
//Function for Conversion of two digit
String twonum(int numq)
{
int numr, nq;
String ltr=\"";
nq = numq / 10;
numr = numq % 10;
if (numq>19)
{
ltr=ltr+tens[nq]+unitdo[numr];
}
else
{
ltr = ltr+unitdo[numq];
}
return ltr;
}
//Function for Conversion of three digit
String threenum(int numq)
{
int numr, nq;
String ltr = "";
nq = numq / 100;
numr = numq % 100;
if (numr == 0)
{
ltr = ltr + unitdo[nq]+digit[1];
}
else
{
ltr = ltr +unitdo[nq]+digit[1]+" and"+twonum(numr);
}
return ltr;
}
}
class originalNumToLetter
{
public static void main(String[] args) throws Exception
{
//Defining variables q is quotient, r is remainder
int len, q=0, r=0;
String ltr = " ";
String Str = "Rupees";
constNumtoLetter n = new constNumtoLetter();
int num = Integer.parseInt(args[0]);
if (num <= 0) System.out.println(\"Zero or Negative number not for conversion");
while (num>0)
{
len = n.numberCount(num);
//Take the length of the number and do letter conversion
switch (len)
{
case 8:
q=num/10000000;
r=num%10000000;
ltr = n.twonum(q);
Str = Str+ltr+n.digit[4];
num = r;
break;
case 7:
case 6:
q=num/100000;
r=num%100000;
ltr = n.twonum(q);
Str = Str+ltr+n.digit[3];
num = r;
break;
case 5:
case 4:
q=num/1000;
r=num%1000;
ltr = n.twonum(q);
Str= Str+ltr+n.digit[2];
num = r;
break;
case 3:
if (len == 3)
r = num;
ltr = n.threenum(r);
Str = Str + ltr;
num = 0;
break;
case 2:
ltr = n.twonum(num);
Str = Str + ltr;
num=0;
break;
case 1:
Str = Str + n.unitdo[num];
num=0;
break;
default:
num=0;
System.out.println(\"Exceeding Crore....No conversion");
System.exit(1);
}
if (num==0)
System.out.println(Str+\" Only");
}
}
}
EDIT:
This sample will convert up to the billions it seems:
import java.text.DecimalFormat;
public class EnglishNumberToWords {
private static final String[] tensNames = {
"",
" ten",
" twenty",
" thirty",
" forty",
" fifty",
" sixty",
" seventy",
" eighty",
" ninety"
};
private static final String[] numNames = {
"",
" one",
" two",
" three",
" four",
" five",
" six",
" seven",
" eight",
" nine",
" ten",
" eleven",
" twelve",
" thirteen",
" fourteen",
" fifteen",
" sixteen",
" seventeen",
" eighteen",
" nineteen"
};
private static String convertLessThanOneThousand(int number) {
String soFar;
if (number % 100 < 20){
soFar = numNames[number % 100];
number /= 100;
}
else {
soFar = numNames[number % 10];
number /= 10;
soFar = tensNames[number % 10] + soFar;
number /= 10;
}
if (number == 0) return soFar;
return numNames[number] + " hundred" + soFar;
}
public static String convert(long number) {
// 0 to 999 999 999 999
if (number == 0) { return "zero"; }
String snumber = Long.toString(number);
// pad with "0"
String mask = "000000000000";
DecimalFormat df = new DecimalFormat(mask);
snumber = df.format(number);
// XXXnnnnnnnnn
int billions = Integer.parseInt(snumber.substring(0,3));
// nnnXXXnnnnnn
int millions = Integer.parseInt(snumber.substring(3,6));
// nnnnnnXXXnnn
int hundredThousands = Integer.parseInt(snumber.substring(6,9));
// nnnnnnnnnXXX
int thousands = Integer.parseInt(snumber.substring(9,12));
String tradBillions;
switch (billions) {
case 0:
tradBillions = "";
break;
case 1 :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
break;
default :
tradBillions = convertLessThanOneThousand(billions)
+ " billion ";
}
String result = tradBillions;
String tradMillions;
switch (millions) {
case 0:
tradMillions = "";
break;
case 1 :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
break;
default :
tradMillions = convertLessThanOneThousand(millions)
+ " million ";
}
result = result + tradMillions;
String tradHundredThousands;
switch (hundredThousands) {
case 0:
tradHundredThousands = "";
break;
case 1 :
tradHundredThousands = "one thousand ";
break;
default :
tradHundredThousands = convertLessThanOneThousand(hundredThousands)
+ " thousand ";
}
result = result + tradHundredThousands;
String tradThousand;
tradThousand = convertLessThanOneThousand(thousands);
result = result + tradThousand;
// remove extra spaces!
return result.replaceAll("^\\s+", "").replaceAll("\\b\\s{2,}\\b", " ");
}
/**
* testing
* #param args
*/
public static void main(String[] args) {
System.out.println("*** " + EnglishNumberToWords.convert(0));
System.out.println("*** " + EnglishNumberToWords.convert(1));
System.out.println("*** " + EnglishNumberToWords.convert(16));
System.out.println("*** " + EnglishNumberToWords.convert(100));
System.out.println("*** " + EnglishNumberToWords.convert(118));
System.out.println("*** " + EnglishNumberToWords.convert(200));
System.out.println("*** " + EnglishNumberToWords.convert(219));
System.out.println("*** " + EnglishNumberToWords.convert(800));
System.out.println("*** " + EnglishNumberToWords.convert(801));
System.out.println("*** " + EnglishNumberToWords.convert(1316));
System.out.println("*** " + EnglishNumberToWords.convert(1000000));
System.out.println("*** " + EnglishNumberToWords.convert(2000000));
System.out.println("*** " + EnglishNumberToWords.convert(3000200));
System.out.println("*** " + EnglishNumberToWords.convert(700000));
System.out.println("*** " + EnglishNumberToWords.convert(9000000));
System.out.println("*** " + EnglishNumberToWords.convert(9001000));
System.out.println("*** " + EnglishNumberToWords.convert(123456789));
System.out.println("*** " + EnglishNumberToWords.convert(2147483647));
System.out.println("*** " + EnglishNumberToWords.convert(3000000010L));
/*
*** zero
*** one
*** sixteen
*** one hundred
*** one hundred eighteen
*** two hundred
*** two hundred nineteen
*** eight hundred
*** eight hundred one
*** one thousand three hundred sixteen
*** one million
*** two millions
*** three millions two hundred
*** seven hundred thousand
*** nine millions
*** nine millions one thousand
*** one hundred twenty three millions four hundred
** fifty six thousand seven hundred eighty nine
*** two billion one hundred forty seven millions
** four hundred eighty three thousand six hundred forty seven
*** three billion ten
**/
}
}
References:
http://www.roseindia.net/tutorial/java/core/convertNumberToWords.html
http://www.java-samples.com/showtutorial.php?tutorialid=1156
http://www.rgagnon.com/javadetails/java-0426.html
Surprisingly it seems that there is no Java library yet which solves this task. Since I found the Python solution in the question comment elegant I converted it to Java:
Text2Digit.java
public class Text2Digit {
final static String[] units = { "zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
"thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
"eighteen", "nineteen" };
final static String[] tens = { "", "", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety" };
final static String[] scales = { "hundred", "thousand", "million",
"billion", "trillion" };
final static Map<String, ScaleIncrement> numWords = new HashMap<>();
static {
numWords.put("and", ScaleIncrement.valueOf(1, 0));
for (int i = 0; i < units.length; i++)
numWords.put(units[i], ScaleIncrement.valueOf(1, i));
for (int i = 0; i < tens.length; i++)
numWords.put(tens[i], ScaleIncrement.valueOf(1, i * 10));
for (int i = 0; i < scales.length; i++) {
int exponent = (i * 3 == 0) ? 2 : i * 3;
numWords.put(scales[i],
ScaleIncrement.valueOf((int) Math.pow(10, exponent), 0));
}
}
public static long convert(String text) {
long current = 0;
long result = 0;
for (String word : text.split(" ")) {
if (!numWords.containsKey(word))
throw new RuntimeException("Illegal word:" + word);
long scale = numWords.get(word).scale;
long increment = numWords.get(word).increment;
current = current * scale + increment;
if (scale > 100) {
result += current;
current = 0;
}
}
return result + current;
}
}
ScaleIncrement.java
public class ScaleIncrement {
long scale;
long increment;
private ScaleIncrement() {}
public static ScaleIncrement valueOf(long scale, long increment) {
ScaleIncrement result = new ScaleIncrement();
result.scale = scale;
result.increment = increment;
return result;
}
}
Test
public static void main(String[] args) {
System.out.println(convert("seven billion one"
+ " hundred million thirty one thousand"
+ " three hundred thirty seven"));
}
Output
7100031337