在Java中舍入一个Bill Total

时间:2014-06-30 03:16:51

标签: java

我试图向应用用户提供他们必须留下的小费,以便他们的账单可以四舍五入到一个不错的数字。例如:

让我们说这个账单是5.21小费@ 20%= 1.04小费。

5.21 + 1.04 =总计6.25。要使小费7.00,他们必须提示1.79。

我认为我的逻辑在这里很好,但我在运行它时显示出奇怪的数字。在logcat中没有错误,所以它在我的代码中。我很确定它在代码的四舍五入部分中,因为我不确定此时我是否正确地执行了此操作。

代码是:

package mkelleyjr.example.tippycalc;



import java.text.DecimalFormat;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;


public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final EditText amt = (EditText) findViewById(R.id.bill_amt);
    final EditText tip = (EditText) findViewById(R.id.bill_percent);
    final TextView result = (TextView) findViewById(R.id.res);
    final TextView total = (TextView) findViewById(R.id.total);
    final TextView round = (TextView) findViewById(R.id.round);


    Button calc = (Button) findViewById(R.id.button1);
            calc.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {

                     DecimalFormat decimalFormat = new DecimalFormat("$0.00");
                     decimalFormat.setMinimumFractionDigits(3);


                 try{

                    double amount = Double.parseDouble(amt.getText().toString());
                    double tip_per = Double.parseDouble(tip.getText().toString());
                    double tip_cal = (amount * tip_per) / 100;

                    double totalcost = amount + tip_cal;

                    decimalFormat.format(totalcost);

                    // round totalcost then perform math on it

                    double rounded = (double)Math.round(totalcost);

                    double roundtotal = rounded - totalcost;


                    result.setText("Tip Amount : " + " $ " + Double.toString(tip_cal));
                    total.setText("Total Cost: "  + " $ " + totalcost);
                    round.setText("Tip:" + roundtotal + " to round bill");



                 }catch (NumberFormatException e) {


                 }

                    }
                });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

}

感谢您提供任何建议或反馈。

3 个答案:

答案 0 :(得分:0)

看到result.setText("Tip Amount : " + " $ " + Double.toString(tip_cal));,我猜你在输出中得到了很多9。双打不能完全存储分数,所以数学将会关闭,但如果你不是金融机构而只是处理< $ 10,000交易,做

result.setText(String.format("Tip Amount :$%.2f", tip_cal));

还有一件事:decimalFormat.format(totalcost);充其量是无操作,最糟糕的是线程安全问题。它没有更改总成本,它返回一个StringBuffer(它显示它的年龄)。

答案 1 :(得分:0)

你真的想在这里使用BigDecimal,而不是Double。正如@David所说,“双打不能完全存储美分”。 BigDecimal类型可以。 BigDecimal可以精确控制精度和舍入。

这是比双打更慢的数据类型,但对于金融应用来说,它远远好得多。

当然,一个简单的小费计算器不是高财务,但基本原则仍然适用。在对诸如美元值之类的事物进行操作时,BigDecimal是一种更好的数据类型。

答案 2 :(得分:0)

有两件事突然袭来......

第一个Math.round可以向下舍入,因此值5.22将向下舍入为6,而不是最多7

现在您可以使用(int)totalcost + 1基本上修剪小数元素或Math.ceil(totalcost),具体取决于您的需要。

第二个是你似乎不理解格式化程序的使用方式

decimalFormat.format(totalcost);

不会做任何事情,数字不受格式化信息的影响。相反,您使用格式化程序以指定的格式返回值的表示...

所有这些都隐藏在我们的腰带之下,像是......

String tipFormat = decimalFormat.format((tip_cal)

DecimalFormat decimalFormat = new DecimalFormat("$0.00");
decimalFormat.setMinimumFractionDigits(2);

try {

    double amount = Double.parseDouble("5.21");
    double tip_per = Double.parseDouble("20");
    double tip_cal = (amount * tip_per) / 100;

    double totalcost = amount + tip_cal;

    double rounded = (int)totalcost + 1;

    double roundtotal = rounded - totalcost;

    System.out.println("Tip Amount : " + decimalFormat.format((tip_cal)));
    System.out.println("Total Cost: " + decimalFormat.format(totalcost));
    System.out.println("Tip: " + decimalFormat.format(roundtotal) + " to round bill");
    System.out.println("Bill Tally: " + decimalFormat.format(totalcost + roundtotal));

} catch (NumberFormatException e) {
    e.printStackTrace();
}

将输出......

Tip Amount : $1.04
Total Cost: $6.25
Tip: $0.75 to round bill
Bill Tally: $7.00

尽管如此,doublefloat并不适合进行货币计算。您可以使用longBigDecimal作为替代方案,例如......

NumberFormat nf = NumberFormat.getCurrencyInstance();

try {

    BigDecimal amount = new BigDecimal(Double.parseDouble("5.21"));
    BigDecimal tip_per = new BigDecimal(Double.parseDouble("20"));

    BigDecimal tip_cal = amount.multiply(tip_per).divide(new BigDecimal(100));
    BigDecimal totalcost = amount.add(tip_cal);

    BigDecimal rounded = totalcost.setScale(0, RoundingMode.CEILING);
    BigDecimal roundtotal = rounded.subtract(totalcost);

    System.out.println("Tip Amount : " + nf.format((tip_cal)));
    System.out.println("Total Cost: " + nf.format(totalcost));
    System.out.println("Tip: " + nf.format(roundtotal) + " to round bill");
    System.out.println("Bill Tally: " + nf.format(totalcost.add(roundtotal)));

} catch (NumberFormatException e) {
    e.printStackTrace();
}

此示例使用NumberFormat类而不是基于DecimalFormat创建自己的格式化程序,不确定它是否在Android中可用,但您应该考虑使用它(或等效的)因为它考虑了用户本地