如何在java中将数字转换为单词-在java中计算货币

如何在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

因此,在另一个项目中,我应该创建一个程序,提示用户输入货币值,并从最高值开始打印出最少数量的纸币和硬币。例如,如果用户输入47.63,则输出为:

0百 二十岁 0十等

我的问题是,当我输入一个特定的值,即186.41,我应该得到100 五十年代 1二十岁 十分之一 1五 1个 四分之一 一毛钱 1分 1便士

然而,我的输出是0便士 这是我的密码:

 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