0

将值四舍五入到特定的小数位数很容易:

public static double round(double x, int n){
    n = (int)Math.pow(n, 10);
    return Math.round(x*n)/n;
}

但是,您能否制定一个算法,根据数字的大小预先假定实际需要四舍五入的小数位数?

我的意思是,如果数字很大(比如100000000.12345),它不需要那么多的小数精度,所以它可以将它四舍五入到小数点后 1 位或 2 位,

而如果一个数字很小(比如0.00012345),它需要最大十进制精度
做这样的事情的想法是什么?

编辑: 示例:

 argument       returned   decnum           comment
123456789.9    123456789     0    //number is way too large so I don't need any decimal places
12345678.99    12345678      0    //number is still very large.
1234567.899    1234567       0    //still...
123456.7899    123456        0    //...
12345.67899    12345         0    //...
1234.567899    1234          0    //It's pretty large now. Still not small enough to get some decimals.
123.4567899    123.4         1    //Now, number is a little average, so 1 decimal place is included.
12.34567899    12.34         2    //The number is normal, so I want a normal 2 decimal places 
1.234567899    1.234         3    //Now it's kinda small, so it now gives 3 decimal places
.1234567899    0.1234        4    //Smaller number, thus greater number of decimal places (4).
.0123456789    0.01234       5    //Even smaller
.0012345678    0.0012345     7    //Larger number of decimal places.
.0001234567    0.0001234567  10   //Smaller and smaller number, greater and greater number of decimals.

我只是在寻找一种方法,当数字接近零时,
我可以增加
小数位数, 并在数字远离零时减少小数位数。

4

3 回答 3

3

You could use BigDecimal. Create a BigDecimal with your double value then check the scale with bigDVariable.scale() and round with the wanted scale depending on the value returned by it and its value. BigDecimal doc.

Edit : You don't seem to worry about how many decimals you have in the first place, the value of your double looks to be the only information that matters. Checking scale() wouldn't matter then.

于 2013-03-12T15:43:50.740 回答
1

If you want high precision (significant digits), you'll have to use BigDecimal instead of double. The BigDecimal round method gives you the number of significant digits you ask for.

Here's something I put together.

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

public class Rounding {

    public static void main(String[] args) {
        BigDecimal number = new BigDecimal(100000000.12345);
        System.out.println("Number: " + number.toPlainString());
        System.out.println(" ");
        for (int precision = 8; precision < 17; precision++) {
            System.out.println("Precision: " + precision + ", result: "
                    + round(number, precision));
        }
    }

    public static String round(BigDecimal number, int precision) {
        MathContext mathContext = new MathContext(precision, 
                RoundingMode.HALF_UP);
        BigDecimal rounded = number.round(mathContext);
        return rounded.toPlainString();
    }

}

And here are the results.

Number: 100000000.12344999611377716064453125

Precision: 8, result: 100000000
Precision: 9, result: 100000000
Precision: 10, result: 100000000.1
Precision: 11, result: 100000000.12
Precision: 12, result: 100000000.123
Precision: 13, result: 100000000.1234
Precision: 14, result: 100000000.12345
Precision: 15, result: 100000000.123450
Precision: 16, result: 100000000.1234500

.

Number: 0.00012344999999999999203137424075293893110938370227813720703125

Precision: 8, result: 0.00012345000
Precision: 9, result: 0.000123450000
Precision: 10, result: 0.0001234500000
Precision: 11, result: 0.00012345000000
Precision: 12, result: 0.000123450000000
Precision: 13, result: 0.0001234500000000
Precision: 14, result: 0.00012345000000000
Precision: 15, result: 0.000123450000000000
Precision: 16, result: 0.0001234500000000000
于 2013-03-12T16:48:03.740 回答
1

从算法的角度来看,我将遵循以下步骤:

  1. 转换基数为 10 格式的数字,例如 123456789.9 -> 1.234567899 * 10^8 和 0.0001234567 -> 1.234567 * 10^-4。

  2. 8例如,在第一个示例和-4最后一个示例中查看 10 的功率因数。

  3. 通过调整一个因子来计算精度位置要求。只是一个例子,功率因数(-1*(p-3))在哪里。p如果数字为负数,则使用“0”。

这将导致以下数字。

argument       decnum      
123456789.9    -1*(8-3) = -5 -> 0
12345678.99    -1*(7-3) = -4 -> 0
1234567.899    -1*(6-3) = -3 -> 0
123456.7899    -1*(5-3) = -2 -> 0
12345.67899    -1*(4-3) = -1 -> 0
1234.567899    -1*(3-3) =  0 -> 0
123.4567899    -1*(2-3) = 1  -> 1
12.34567899    -1*(1-3) = 2  -> 2
1.234567899    -1*(0-3) = 3  -> 3
.1234567899    -1*(-1-3) = 4 -> 4
.0123456789    -1*(-2-3) = 5  -> 5
.0012345678    -1*(-3-3) = 6  -> 6
.0001234567    -1*(-4-3) = 7  -> 7

这将非常接近您正在寻找的内容。如果您真的想要,请尝试调整因子和公式以更接近(这只是一种算法/方法)。

于 2013-03-12T16:18:13.423 回答