I've been messing around trying to figure out why I'm getting this compiler error for a few hours, and I'm just not sorting it out. Any help would be appreciated.

Thanks,
David

Code:

package dladoucer_week5;

import java.util.Scanner;

public class Main {

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

    int cont = 0;
    double tax = .00346;
    int oldReading;
    int newReading;
    int usage;
    double rate = 0;
    double subtotal;
    double taxes;
    double total;

    while (cont == 0) {
    
         System.out.println("Welcome to the City Power Bill Calculator!");
         System.out.println("Please enter your previous meter reading:");
         oldReading = input.nextInt();
         System.out.println("Please enter your current meter reading:");
         newReading = input.nextInt();
         usage = newReading - oldReading;
         if (usage <= 500) {
             rate = .0809;
           subtotal = rate * usage;
         taxes = subtotal * tax;
       total = subtotal + taxes;
         System.out.printf("Your usage was: %d KwHs\n",usage);
         System.out.printf("Your rate is: $ %5.4d/KwH\n",rate);
         System.out.printf("Your Subtotal will be: $%.2d\n",subtotal);
         System.out.printf("Your taxes are: %.2d\n",taxes);
         System.out.printf("Your total bill this month is: %.2d\n",total);
         System.out.println("\nCalculate a new usage? "
                 + "(-1 to Exit, 0 to Continue)");
         cont = input.nextInt();}
 else if (usage >= 501 && usage <= 900) {
     rate = .091;
   subtotal = rate * usage;
         taxes = subtotal * tax;
         total = subtotal + taxes;
         System.out.printf("Your usage was: %d KwHs\n",usage);
         System.out.printf("Your rate is: $ %5.4d/KwH\n",rate);
         System.out.printf("Your Subtotal will be: $%.2d\n",subtotal);
         System.out.printf("Your taxes are: %.2d\n",taxes);
         System.out.printf("Your total bill this month is: %.2d\n",total);
   System.out.println("\nCalculate a new usage? "
                 + "(-1 to Exit, 0 to Continue)");
         cont = input.nextInt();}
 else if (usage > 901) {
     rate = .109;
         subtotal = rate * usage;
         taxes = subtotal * tax;
         total = subtotal + taxes;
         System.out.printf("Your usage was: %d KwHs\n",usage);
         System.out.printf("Your rate is: $ %5.4d/KwH\n",rate);
         System.out.printf("Your Subtotal will be: $%.2d\n",subtotal);
         System.out.printf("Your taxes are: %.2d\n",taxes);
         System.out.printf("Your total bill this month is: %.2d\n",total);
         System.out.println("\nCalculate a new usage? "
                 + "(-1 to Exit, 0 to Continue)");
         cont = input.nextInt();}
         }
    }
    }

When I run it I get:

run:
Welcome to the City Power Bill Calculator!
Please enter your previous meter reading:
750
Please enter your current meter reading:
1235
Your usage was: 485 KwHs
Exception in thread "main" java.util.IllegalFormatPrecisionException: 4
        at java.util.Formatter$FormatSpecifier.checkInteger(Formatter.java:2892)
        at java.util.Formatter$FormatSpecifier.<init>(Formatter.java:2643)
        at java.util.Formatter.parse(Formatter.java:2480)
        at java.util.Formatter.format(Formatter.java:2414)
        at java.io.PrintStream.format(PrintStream.java:920)
        at java.io.PrintStream.printf(PrintStream.java:821)
        at dladoucer_week5.Main.main(Main.java:38)
Java Result: 1
BUILD SUCCESSFUL (total time: 9 seconds)

Dani AI

Generated

The exception you saw (IllegalFormatPrecisionException: 4) is coming from your printf format strings. Java's Formatter treats the ".precision" part differently depending on the conversion letter: precision is valid for floating conversions (like f) and strings, but not for integer conversions (d). Putting .4 or .2 in a %d specifier (for example %5.4d or %.2d) causes that exception. As noted, the quick fix is to use the floating-point conversion (%f) for double values (e.g. rates, subtotal, taxes, total) and keep %d only for integer values like usage.

A few practical improvements to avoid similar problems and make the output nicer:

  • Use %.4f for the rate (four decimal places) and %.2f for currency values. Use %,.2f when you want grouping commas. Prefer %n instead of \n for portable newlines.
  • For money calculations, consider BigDecimal and setScale(2, RoundingMode.HALF_EVEN) before formatting to avoid floating-point rounding surprises. Then format with NumberFormat.getCurrencyInstance() for locale-aware output.

Example (not a drop-in replacement for your posted code — shows the idea):

NumberFormat money = NumberFormat.getCurrencyInstance();
BigDecimal subtotal = BigDecimal.valueOf(rate).multiply(BigDecimal.valueOf(usage)).setScale(2, RoundingMode.HALF_EVEN);
BigDecimal taxes = subtotal.multiply(BigDecimal.valueOf(TAX)).setScale(2, RoundingMode.HALF_EVEN);
BigDecimal total = subtotal.add(taxes);
System.out.println("Subtotal: " + money.format(subtotal));
System.out.println("Taxes:    " + money.format(taxes));
System.out.println("Total:    " + money.format(total));

Also follow 's refactoring advice: extract a small rateFor(usage) function, make TAX a static final constant, validate input (check newReading >= oldReading), and guard scanner reads with hasNextInt() or catch InputMismatchException. Those changes will make the program safer and the formatting errors easier to spot.

Recommended Answers

All 3 Replies

Member Avatar for Member #887084

just change your .2d to .2f, for format.

Member Avatar for Member #887084

Also, its a good idea to break big chunks of repeated code into methods.

For instance, you could have a method called calculate that takes in a usage parameter.

private void calculate(int usage) {
		double rate;
		if (usage <= 500) 
			rate = 0.0809;
		else if (usage <= 900) 
			rate = 0.091;
		else 
			rate = 0.109;
		
		String tab = "    ";
		System.out.println();
		System.out.printf(tab + "   Usage:   %d KwHs\n", usage);
		System.out.printf(tab + "    Rate: $ %.4f / KwH\n", rate);
		System.out.printf(tab + "SubTotal: $ %.2f\n", rate * usage);
		System.out.printf(tab + "   Taxes: $ %.2f\n", rate * usage * TAX);
		System.out.printf(tab + "   Total: $ %.2f\n", rate * usage * (1 + TAX));
		
		System.out.println();
	}

Also, it is good practice to only create variables that cannot be replicated by some function. Rate is a good one to store as a variable, because it is used throughout the method. Subtotal should not be stored; you can simply call: "rate * usage" every time...no need to store it.

Additionally, variables that are used throughout your program and never change, like tax, should be finalized:

private final double TAX = 0.00346;

Note the uppercase syntax indicating a final variable.

Thanks, worked perfectly. I appreciate the advice on the other changes for cleaner code as well, thank you again.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.