为什么我的格式如此奇怪?

时间:2018-02-10 22:47:31

标签: java formatting printf number-formatting

我的代码格式有问题。最后,它应该打印出它的结果。我正在使用printf语句,但它返回的数字并不像我需要的那样精确。例如,如果一个数字应为76.83200000000001,则返回为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);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

好吧,我删除了我以前的答案,因为它是绝对错误的(感谢@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(...);,只需将%f标志替换为%s - 在这种情况下,参数将转换为字符串(结果通过调用获得参数的toString()方法,这就是你所需要的)。例如,您可以重写此行:

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

如下:

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

这将打印population的确切值。

答案 1 :(得分:0)

检查此帖子的第一个答案,它可能会有所帮助。

How many significant digits have floats and doubles in java?

  

了解精度不均匀且非常重要   这并不是对整数的精确存储。