为什么我的格式这么奇怪?

Why is my formatting so strange?

我的代码格式有问题。最后,它应该打印出它的结果。我正在使用 printf 语句,但它 returns 数字并不像我需要的那样精确。例如,如果一个数字应为 76.83200000000001,则 returns 为 76.83200。它还在数字末尾添加了不必要的零,如果一个数字应该是 28.0,它就会变成 28.000000。如果可能的话,我们可以不用 BigDecimal 变量吗?到目前为止,这是我的代码(注意:一些字符串前面有空格,那是因为我要提交的网站出于某种原因需要这样做):

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);
        }
    }
}

检查此线程的第一个答案,可能会有帮助。

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.

好吧,我删除了我之前的回答,因为它是绝对错误的(感谢@JohnKugelman 指出了这一点)。我认为由于转换为 float 而导致精度丢失,但事实并非如此。

根据 formatter documentation,使用 %f 标志时会发生以下情况:

  • 震级m(自变量的绝对值)格式为 m 的整数部分,没有前导零,后跟 小数分隔符后跟一位或多位小数位,表示 m.

  • 的小数部分
  • m的小数部分的结果位数等于精度。 如果没有指定精度那么 默认值为 6

  • 如果精度小于会出现的位数 返回的字符串中的小数点后 Float.toString(float)Double.toString(double) 分别, 然后将使用四舍五入算法对该值进行四舍五入。 否则,可能会附加零以达到精度。

这就是为什么你得到不必要的零和削减数字的原因。

文档建议使用 Float.toString(float)Double.toString(double) 作为值的规范表示。

如果你想使用System.out.printf(...);,你可以只用%s替换你的%f标志——在这种情况下参数将被转换为一个字符串(得到的结果通过调用参数的 toString() 方法,这就是您所需要的)。例如,您可以重写此行:

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

如下:

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

这将打印出您 population 的准确值。