0

So here is my task:

A postal company for a package charges $15 for the first pound or a fraction thereof and $10 per pound for anything over one pound. Write a program that prints the charge of a package.

Variables:

weight

First execution:

Weight? -12 Weight must be a positive number.

Second Execution:

Weight? 0 Weight must be a positive number.

Third Execution:

Weight? 2 Pay: $25.00

Forth Execution:

Weight? 2.8 Pay: $33.00

Fifth Execution:

Weight? 2.07 Pay: $25.70

and Here is the code I have developed so far:

 import java.text.DecimalFormat;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);
        double weight;
        double cost = 15.00; // set first pound to $15
        double output = 0;
        System.out.print("Weight?: ");
        weight = keyboard.nextDouble();
        if (weight <= 0) {
            System.out.println("Weight must be a positive number.");
        } else if (weight == 1) {
            // Print the charge of the package
            output = output + cost;
            DecimalFormat money = new DecimalFormat("$0.00");
            System.out.println("Pay: " + money.format(output));
        } else {
            for (double i = 1; i < weight; i = i + .01) {
                if (weight > 1) {
                    output = output + (1 / 10.00);
                }
            }
            // Print the charge of the package
            output = output + cost;
            DecimalFormat money = new DecimalFormat("$0.00");
            System.out.println("Pay: " + money.format(output));

        }
    }
}

Everything works, but what I can't figure out is why (especially in the Fourth and Fifth Execution) is the final output always .10 cents off. Can anyone help me get to the accuracy I need?

3 Answers3

0

This: double i = 1; i < weight; i = i + .01 could be your problem.

Doubles are not exact for decimal math. You're expecting i == weight, at which point the loop should stop, but it might not because i + .01 (however many times) is a tiny fraction less than weight.

My advice is to ditch the loop. If the package is over 1 lb, just subtract one pound from the weight, multiply by the $10 per pound, and then round to the two decimal places you need (NOTE: round it according to how it's spec'd to be rounded, don't just let the conversion from double to decimal do it on its own. There are multiple ways to round something, and decimal does not magically know which one is right for your problem.)

EDIT: Look at your solution, is it supposed to only work to a resolution of 1/10 of a lb? If so, start by rounding the weight. Again, round it according to how it needs to be rounded (down, up, or nearest).

0

If I understand the question correctly, you should never have any fractional dollar amount because anything over a pound is automatically rounded up to the next pound. ie: 2.01 lbs would become 3 lbs. If this is correct, then you could use Math's ceil function to round the weight up to the nearest whole pound, then do something like this:

public class Main {
public static void main(String[] args) {
    Scanner keyboard = new Scanner(System.in);
    double weight;
    double cost = 15.00; // set first pound to $15
    double output = 0;
    System.out.print("Weight?: ");
    weight = keyboard.nextDouble();
    if (weight <= 0) {
        System.out.println("Weight must be a positive number.");
    } else if (weight == 1) {
        // Print the charge of the package
        output = output + cost;
        DecimalFormat money = new DecimalFormat("$0.00");
        System.out.println("Pay: " + money.format(output));
    } else {
        double temp = (Math.ceil(weight)) - 1;
        for(double i = temp; i > 0; i-- ) {
            output += 10;
        }
        output += cost;
        DecimalFormat money = new DecimalFormat("$0.00");
        System.out.println("Pay: " + money.format(output));

    }
}

}

This way, you don't need to bother with 10 cent increments. I hope this helps. Let me know if you have any questions.

jeffkempf
  • 288
  • 1
  • 3
  • 11
  • See my answer- using a double for a comparison like that is bad news. You're rounding it anyway, use a nice and predictable int. – Dark Squirtings Sep 15 '15 at 20:22
0

Here is what I came up with:

    Scanner keyboard = new Scanner(System.in);
    double weight;
    double cost = 15.00; // set first pound to $15
    double output = 0;
    System.out.print("Weight?: ");
    weight = keyboard.nextDouble();
    if (weight <= 0) {
        System.out.println("Weight must be a positive number.");
    } else {
        // Print the charge of the package
        if (weight > 1) {
            output = cost + ((weight-1) * 10);
        } else {
            output = cost;
        }
        DecimalFormat money = new DecimalFormat("$0.00");
        System.out.println("Pay: " + money.format(output));
    }

This should handle all of your cases, as well as numbers between 0 and 1 assuming it's $1 per 0.1 lbs. Instead of your for-loop, you can just use the cost + ((weight-1) * 10) formula. I removed the check to see if weight was equal to 1 because it's handled in the else clause.

Evan LaHurd
  • 977
  • 2
  • 14
  • 27