如何在java中将数字转换为单词-在java中计算货币
因此,在另一个项目中,我应该创建一个程序,提示用户输入货币值,并从最高值开始打印出最少数量的纸币和硬币。例如,如果用户输入47.63,则输出为: 0百 二十岁 0十等 我的问题是,当我输入一个特定的值,即186.41,我应该得到100 五十年代 1二十岁 十分之一 1五 1个 四分之一 一毛钱 1分 1便士 然而,我的输出是0便士 这是我的密码:如何在java中将数字转换为单词-在java中计算货币,java,Java,因此,在另一个项目中,我应该创建一个程序,提示用户输入货币值,并从最高值开始打印出最少数量的纸币和硬币。例如,如果用户输入47.63,则输出为: 0百 二十岁 0十等 我的问题是,当我输入一个特定的值,即186.41,我应该得到100 五十年代 1二十岁 十分之一 1五 1个 四分之一 一毛钱 1分 1便士 然而,我的输出是0便士 这是我的密码: public class CountingMoney { public static BufferedReader delta = new
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");
}
}
你所面临的问题最好解释清楚 为了克服这种使用。但是,请确保设置了和。否则,您可能会得到java.lang.arithmetricException:非终止十进制扩展;没有可精确表示的十进制结果。在你的除法手术中 有关如何修改的示例代码:
amount = bigDecimal.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).intValue();
bigDecimal = bigDecimal.subtract(new BigDecimal(amount * 100));
System.out.println(amount+ " Hundreds");
当您使用int将double转换为int时,它总是向下舍入,无论double值与正上方的整数有多接近。double不能准确地表示186.41这样的值,因为它们存储在二进制而不是十进制中。当你开始用它们进行大量计算时,误差开始累积
当我尝试您的程序,并显示要舍入的值时:
System.out.println("result of division is " + (input/.01));
amount = (int) (input/.01);
input -= amount * .01;
System.out.println(amount + " Pennies");
它显示
result of division is 0.999999999999658
这非常非常接近于1,因此没有累积太多的误差。但这并不准确。由于施法到整数舍入,数量将为0
有两种方法可以解决此问题:
1按照另一个答案中的建议使用BigDecimal。这是处理金钱的首选方法。它将精确地表示小数位数
2使用Math.round代替int,例如
double上的Math.round返回一个long,因此您仍然需要进行转换,但它是从一个整数转换为另一个整数,因此不涉及舍入
我仍然建议使用BigDecimal。然而,这应该可以帮助您看到,在其他情况下,您确实需要处理double,您需要注意您所做的取整类型。强制转换为int通常是错误的,这取决于您尝试执行的操作 您可以使用下面的代码,该代码在 有关更多参考和讨论,请参考 希望它能解决你的需要 包com.test 导入java.text.DecimalFormat 公共类英语数字词{
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));
}
}下面的java程序演示如何将数字从零转换为一百万 NumberToStringLiteral类:
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;
}
}
注意:我使用了常量变量的所有三个枚举,您也可以使用数组
希望这能对您有所帮助,如果您在评论部分有任何疑问,请告诉我。看起来可能是浮点舍入错误。如果你关心准确性,就永远不要用double来换取一笔钱。否则,很小的错误就会悄悄地出现,就像你看到的那样。请尝试使用BigDecimal而不是double。@DavidWallace谢谢您much@DavidWallace关于浮点错误的看法是正确的——像186.41这样的值不能精确地表示为双精度。然而,这里真正的问题是,当你将一个double转换为int时,它总是向下舍入。如果在将输入除以0.01之前打印输入,则显示0.00999999996581。当你除以0.01,你会得到0.999999996581。这非常接近1,因此浮点错误量非常小。但它仍然小于1,这意味着int的结果是0。使用Math.round而不是强制转换为int可以解决这个问题。。。。。。但我仍然建议使用BigDecimal,或者使用整数来完成所有操作,让金额表示美分的数量而不是美元的数量。这与OP的原始代码有很大不同。这似乎是一个完全不同问题的好答案。
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;
}
}
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());
}
}
}
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());
}
}
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());
}
}
one hundred and twenty three thousand four hundred and fifty six