Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

java - 如何在Java中将数字四舍五入到小数点后n位(How to round a number to n decimal places in Java)

What I would like is a method to convert a double to a string which rounds using the half-up method - ie if the decimal to be rounded is 5, it always rounds up to the next number.

(我想要的是一种将双精度数转换为使用Half-up方法取整的字符串的方法-即,如果要取整的小数为5,则始终将其取整为下一个数字。)

This is the standard method of rounding most people expect in most situations.

(这是大多数人在大多数情况下期望的四舍五入标准方法。)

I also would like only significant digits to be displayed - ie there should not be any trailing zeroes.

(我也希望只显示有效数字-即不应有任何尾随零。)

I know one method of doing this is to use the String.format method:

(我知道这样做的一种方法是使用String.format方法:)

String.format("%.5g%n", 0.912385);

returns:

(返回:)

0.91239

which is great, however it always displays numbers with 5 decimal places even if they are not significant:

(这很好,但是即使数字不重要,它也始终显示5位小数:)

String.format("%.5g%n", 0.912300);

returns:

(返回:)

0.91230

Another method is to use the DecimalFormatter :

(另一种方法是使用DecimalFormatter :)

DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);

returns:

(返回:)

0.91238

However as you can see this uses half-even rounding.

(但是,如您所见,这使用了半数舍入。)

That is it will round down if the previous digit is even.

(如果前一位是偶数,它将四舍五入。)

What I'd like is this:

(我想要的是这样的:)

0.912385 -> 0.91239
0.912300 -> 0.9123

What is the best way to achieve this in Java?

(用Java实现此目标的最佳方法是什么?)

  ask by Alex Spurling translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Use setRoundingMode , set the RoundingMode explicitly to handle your issue with the half-even round, then use the format pattern for your required output.

(使用setRoundingMode ,显式设置RoundingMode以处理半个半个回合的问题,然后将格式模式用于所需的输出。)

Example:

(例:)

DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
    Double d = n.doubleValue();
    System.out.println(df.format(d));
}

gives the output:

(给出输出:)

12
123.1235
0.23
0.1
2341234.2125

EDIT : The original answer does not address the accuracy of the double values.

(编辑 :原始答案未解决双精度值的准确性。)

That is fine if you don't care much whether it rounds up or down.

(如果您不在乎它是向上还是向下,那很好。)

But if you want accurate rounding, then you need to take the expected accuracy of the values into account.

(但是,如果要精确舍入,则需要考虑值的预期准确性。)

Floating point values have a binary representation internally.

(浮点值在内部具有二进制表示形式。)

That means that a value like 2.77395 does not actually have that exact value internally.

(这意味着像2.77395这样的值实际上在内部没有该确切值。)

It can be slightly larger or slightly smaller.

(它可以稍大或略小。)

If the internal value is slightly smaller, then it will not round up to 2.7740.

(如果内部值稍小,则不会舍入到2.7740。)

To remedy that situation, you need to be aware of the accuracy of the values that you are working with, and add or subtract that value before rounding.

(为了解决这种情况,您需要了解所使用的值的准确性,并在舍入之前添加或减去该值。)

For example, when you know that your values are accurate up to 6 digits, then to round half-way values up, add that accuracy to the value:

(例如,当您知道自己的值在6位数字之内是正确的,然后将其四舍五入时,请将精度添加到值中:)

Double d = n.doubleValue() + 1e-6;

To round down, subtract the accuracy.

(要舍入,请减去精度。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...