【问题标题】:Preserving Accuracy When Formatting a Floating Point Number to Display With Two-point Precison (Java)格式化浮点数以两点精度显示时保持准确性 (Java)
【发布时间】:2016-08-21 04:07:21
【问题描述】:

这是程序。它旨在根据工作时间、小时费率、预扣税款等计算员工的净工资。它计算正确,但双点精度格式会四舍五入最后一位小数,失去计算的准确性。

示例输入:

姓名:史密斯
本周工作时间:10
每小时费率:6.75
联邦预扣税:20%
州税预扣:9%

输出:

总结

员工:史密斯
总工资:67.50
联邦预扣税:13.50
州预扣税:6.08
总扣除额:19.58
净工资:47.93

import java.util.*;
public class Payroll
{
    static Scanner key = new Scanner(System.in);
    public Payroll()
    {
        System.out.print("Name: ");
        String name = key.next();

        System.out.print("Hours worked this week: ");
        int hoursWorked = key.nextInt();
        System.out.print("Hourly rate: ");
        double payRate = key.nextDouble();

        double payPreTax = hoursWorked * payRate;

        System.out.print("Federal tax withhold: ");
        String fedTaxStr = key.next().replace("%", "");
        double fedTax = ((Double.parseDouble(fedTaxStr)) / 100) * payPreTax;

        System.out.print("State tax withold: ");
        String stateTaxStr = key.next().replace("%", "");
        double stateTax = ((Double.parseDouble(stateTaxStr)) / 100) * payPreTax;

        double amountWithheld = fedTax + stateTax;

        double payPostTax = payPreTax - amountWithheld;

        System.out.printf("\nSummary\n\nEmployee: " + name + "\nGross Pay: %.2f\nFederal Withholding: %.2f\nState Withholding: %.2f\nTotal Deduction: %.2f\nNet Pay: %.2f", payPreTax, fedTax, stateTax, amountWithheld, payPostTax);
    }
    public static void main(String[] args)
    {
        new Payroll();
    }

}

请见谅;我是一年级。

【问题讨论】:

  • 您的预期输出是什么?
  • @Shahid 摘要员工:Smith Gross 工资:67.50 联邦预扣税:13.50 州预扣税:6.07 总扣除额:19.57 净工资:47.93
  • 您应该在货币方面使用浮点运算。使用BigDecimal

标签: java


【解决方案1】:

在格式化浮点数以两点精度显示时保持准确性

你要求的是自相矛盾的/不可能的。

你说:

它计算正确,但双点精度格式将最后一位小数四舍五入,失去了计算的准确性。

没错。浮点计算可能至少精确到小数点后 10 位。正如您所注意到的,当您在printf 调用中使用%.2f 格式化数字时,实际上会发生精度损失(舍入)。

简单地说,你不能“保持准确性”,也不能打印出只有 2 个小数点精度的数字。

简单的解决方法是在小数点后多打印几位;即对数字使用不同的格式说明符。 (例如 ...%.4f 会给你小数点后 4 位数字!)

我建议您阅读javadocs for Formatter,它解释了格式说明符的含义。


实际上,还有另一种看待这个的方式。您在这里使用double 进行计算。 double 是二进制(base-2)浮点表示。许多十进制数不能用二进制浮点数精确表示。 (出于同样的原因,1 / 3 不能用十进制浮点精确表示。)

在会计软件中处理此问题的常规方法是将货币值表示为整数(例如整数美分)或十进制浮点表示。在 Java 中,BigDecimal 是表示十进制浮点的标准方式。它可以应对任意精度。

【讨论】:

  • 那么将所有双精度数转换为整数,在我的计算中使用整数,然后将答案转换成双精度数?
  • 如果你打算使用整数,你会使用intlong(或BigInteger)。同上BigDecimal
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
  • 2017-01-19
  • 2021-06-12
  • 2017-05-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多