简体   繁体   中英

Why is my formatting so strange?

I have a problem with my code's formatting. At the end, it's supposed to print out its results. I am using a printf statement, but it returns numbers that aren't as precise as I need them to be. For example, if one number should be 76.83200000000001, it returns as 76.83200. It is also adding unnecessary zeros at the end of numbers, and if a number should be 28.0, it turns into 28.000000. If possible, can we do this without a BigDecimal variable? Here's my code so far (NOTE: there are spaces in front of some strings, that's because the website I'm submitting to requires that for some reason):

import java.util.Scanner;
public class Population {
    public static void main(String[] args) {
        Scanner stdin = new Scanner(System.in);
        double startingNumber, dailyIncrease, daysWillMultiply, temp, population;

        System.out.print("Enter the starting number organisms: ");
        startingNumber = stdin.nextDouble();
        while(startingNumber < 2) {
            System.out.print("Invalid. Must be at least 2. Re-enter: ");
            startingNumber = stdin.nextDouble();
        }

        System.out.print("Enter the daily increase: ");
        dailyIncrease = stdin.nextDouble();
        while(dailyIncrease < 0) {
            System.out.print("Invalid. Enter a non-negative number: ");
            dailyIncrease = stdin.nextDouble();
        }

        System.out.print("Enter the number of days the organisms will multiply: ");
        daysWillMultiply = stdin.nextDouble();
        while(daysWillMultiply < 1) {
            System.out.print("Invalid. Enter 1 or more: ");
            daysWillMultiply = stdin.nextDouble();
        }


        temp = startingNumber * dailyIncrease;
        population = startingNumber;

        System.out.println("Day\t\tOrganisms");
        System.out.println("-----------------------------");
        System.out.println("1\t\t" + startingNumber);
        for (int x = 2; x <= daysWillMultiply; x++) {
            population += temp;
            temp = population * dailyIncrease;
            System.out.printf(x + "\t\t%f\n", population);
        }
    }
}

Well, I deleted my previous answer as it was absolutely wrong (thanks to @JohnKugelman for pointing this out). I thought that precision is lost due to converting to float , but it is not true.

According to the formatter documentation , here's what happens when %f flag is used:

  • The magnitude m (absolute value of the argument) is formatted as the integer part of m , with no leading zeroes, followed by the decimal separator followed by one or more decimal digits representing the fractional part of m .

  • The number of digits in the result for the fractional part of m is equal to the precision. If the precision is not specified then the default value is 6

  • If the precision is less than the number of digits which would appear after the decimal point in the string returned by Float.toString(float) or Double.toString(double) respectively, then the value will be rounded using the round half up algorithm. Otherwise, zeros may be appended to reach the precision.

That's why you get unnecessary zeros and cut digits.

The documentation suggests to use Float.toString(float) or Double.toString(double) for a canonical representation of the value.

If you want to use System.out.printf(...); , you can just replace your %f flag with %s - in this case the argument will be converted to a string (the result is obtained by invoking the argument's toString() method, and this is what you need). For example, you could rewrite this line:

System.out.printf(x + "\t\t%f\n", population); 

as follows:

System.out.printf("%d\t\t%s\n", x, population);

This will print the exact value of your population .

Check first answer of this thread, it maybe helpful.

How many significant digits have floats and doubles in java?

It's important to understand that the precision isn't uniform and that this isn't an exact storage of the numbers as is done for integers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM