You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java公交售票机找零计算异常:预期1.90欧元却得1.85欧元

浮点精度错误导致找零计算偏差的解决方案

问题根源

你遇到的问题核心是浮点数的精度限制:double类型无法精确表示所有十进制小数(比如2.10),在多次加减运算后,误差会被累积放大,导致最终找零计算结果偏离预期。同时代码中还存在几处变量拼写错误,进一步加剧了逻辑异常:

  • nochZuZahlen 应该是 stillToPay
  • rueckgabebetrag 应该是 Change

修复方案

解决浮点数精度问题的标准做法是用整数处理金额(以最小货币单位“分”为单位),避免浮点运算带来的误差。同时修正所有变量拼写错误,确保逻辑正常运行。

修复后的完整代码

import java.util.Scanner;

class Fahrkartenautomat {
    public static void main(String[] args) {
        Scanner tastatur = new Scanner(System.in);

        int amountToPay; // 单位:分
        int depositedTotalAmount; // 单位:分
        int insertionOfCoins; // 单位:分
        int change; // 单位:分
        int stillToPay; // 单位:分
        double ticketPriceInput; // 用于接收用户输入的欧元值
        int ticketPrice; // 转换为分
        int numberOfTickets;

        // 输入金额
        System.out.print("Ticketpreis (Euro): ");
        ticketPriceInput = tastatur.nextDouble();
        // 将欧元转换为分,四舍五入避免转换误差
        ticketPrice = (int) Math.round(ticketPriceInput * 100);
        System.out.print("Anzahl der Tickets: ");
        numberOfTickets = tastatur.nextInt();
        amountToPay = ticketPrice * numberOfTickets;

        // 投币过程
        depositedTotalAmount = 0;
        stillToPay = 0;
        while (depositedTotalAmount < amountToPay) {
            stillToPay = amountToPay - depositedTotalAmount;
            // 转换回欧元格式输出
            System.out.printf("Noch zu zahlen: %.2f Euro%n", stillToPay / 100.0);
            System.out.print("Eingabe (mind. 5 Cent, höchstens 2 Euro): ");
            double coinInput = tastatur.nextDouble();
            insertionOfCoins = (int) Math.round(coinInput * 100);
            depositedTotalAmount += insertionOfCoins;
        }

        // 输出车票
        System.out.println("\nFahrschein wird ausgegeben");
        for (int i = 0; i < 8; i++) {
            System.out.print("=");
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("\n\n");

        // 计算找零
        change = depositedTotalAmount - amountToPay;
        if (change > 0) {
            System.out.printf("Der Rückgabebetrag in Höhe von %.2f Euro%n", change / 100.0);
            System.out.println("wird in folgenden Münzen ausgezahlt:");

            // 按面值从大到小找零
            while (change >= 200) { // 2欧元 = 200分
                System.out.println("2 Euro");
                change -= 200;
            }
            while (change >= 100) { // 1欧元 = 100分
                System.out.println("1 Euro");
                change -= 100;
            }
            while (change >= 50) { // 50分
                System.out.println("50 Cent");
                change -= 50;
            }
            while (change >= 20) { // 20分
                System.out.println("20 Cent");
                change -= 20;
            }
            while (change >= 10) { // 10分
                System.out.println("10 Cent");
                change -= 10;
            }
            while (change >= 5) { // 5分
                System.out.println("5 Cent");
                change -= 5;
            }
        }

        System.out.println("\nVergessen Sie nicht, den Fahrschein\n" + "vor Fahrtantritt entwerten zu lassen!\n"
                + "Wir wünschen Ihnen eine gute Fahrt.");

        tastatur.close();
    }
}

关键修复点说明

  • 金额单位转换:将所有金额计算转换为以“分”为单位的整数运算,彻底避免浮点精度误差。
  • 输入处理:用户输入的欧元值通过Math.round()转换为分,防止转换时的截断误差。
  • 变量修正:修复所有拼写错误的变量名,确保逻辑流程正常。
  • 输出格式化:在需要显示欧元时,将整数分转换为double类型的欧元值,保证显示格式正确。

内容的提问来源于stack exchange,提问作者Dylan Grech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 08:45:29