Java公交售票机找零计算异常:预期1.90欧元却得1.85欧元
浮点精度错误导致找零计算偏差的解决方案
问题根源
你遇到的问题核心是浮点数的精度限制:double类型无法精确表示所有十进制小数(比如2.10),在多次加减运算后,误差会被累积放大,导致最终找零计算结果偏离预期。同时代码中还存在几处变量拼写错误,进一步加剧了逻辑异常:
nochZuZahlen应该是stillToPayrueckgabebetrag应该是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
相关产品推荐
相关产品推荐

