Вокруг двойного до 3 значащих цифр - PullRequest
24 голосов
/ 26 сентября 2011

Кто-нибудь знает, как я могу округлить двойное значение до 3 значащих цифр, как примеры на этом сайте

http://www.purplemath.com/modules/rounding2.htm

Ответы [ 5 ]

66 голосов
/ 26 сентября 2011
double d = ...;
BigDecimal bd = new BigDecimal(d);
bd = bd.round(new MathContext(3));
double rounded = bd.doubleValue();
2 голосов
/ 05 февраля 2016
    public String toSignificantFiguresString(BigDecimal bd, int significantFigures ){
    String test = String.format("%."+significantFigures+"G", bd);
    if (test.contains("E+")){
        test = String.format(Locale.US, "%.0f", Double.valueOf(String.format("%."+significantFigures+"G", bd)));
    }
    return test;
}
1 голос
/ 18 октября 2017

Если вы хотите сделать это вручную:

import java.lang.Math;

public class SigDig {

  public static void main(String[] args) {
    System.out.println("   -123.456   rounded up   to 2 sig figures is " + sigDigRounder(-123.456, 2,  1));
    System.out.println("     -0.03394 rounded down to 3 sig figures is " + sigDigRounder(-0.03394, 3, -1));
    System.out.println("    474       rounded up   to 2 sig figures is " + sigDigRounder(474, 2,  1));
    System.out.println("3004001       rounded down to 4 sig figures is " + sigDigRounder(3004001, 4, -1));
  }

  public static double sigDigRounder(double value, int nSigDig, int dir) {

    double intermediate = value/Math.pow(10,Math.floor(Math.log10(Math.abs(value)))-(nSigDig-1));

    if(dir > 0)      intermediate = Math.ceil(intermediate);
    else if (dir< 0) intermediate = Math.floor(intermediate);
    else             intermediate = Math.round(intermediate);

    double result = intermediate * Math.pow(10,Math.floor(Math.log10(Math.abs(value)))-(nSigDig-1));

    return(result);

  }
}

Приведенный выше метод округляет двойное число до нужного числа значащих цифр, обрабатывает отрицательные числа и может явно указывать округление вверх или вниз

0 голосов
/ 26 сентября 2011

как я могу округлить двойное значение до 3 значащих цифр

Ты не можешь. Двойники представляют в двоичном виде. У них нет десятичных разрядов для округления. Единственный способ получить определенное количество десятичных разрядов - это преобразовать его в десятичное число и оставить его там. В тот момент, когда вы преобразуете его обратно в двойное, вы снова теряете десятичную точность.

Для всех поклонников, здесь и в других местах, конвертирования в другие радиусы и обратно или умножения и деления на степени десяти, пожалуйста, отобразите полученное двойное значение% 0,001 или что-то еще, что требует требуемая точность, и объясните результат.

РЕДАКТИРОВАТЬ: В частности, сторонники этих методов должны объяснить 92% частоту отказов следующего кода:

public class RoundingCounterExample
{
    static float roundOff(float x, int position)
    {
        float a = x;
        double temp = Math.pow(10.0, position);
        a *= temp;
        a = Math.round(a);
        return (a / (float)temp);
    }

    public static void main(String[] args)
    {
        float a = roundOff(0.0009434f,3);
        System.out.println("a="+a+" (a % .0001)="+(a % 0.001));
        int count = 0, errors = 0;
        for (double x = 0.0; x < 1; x += 0.0001)
        {
            count++;
            double d = x;
            int scale = 2;
            double factor = Math.pow(10, scale);
            d = Math.round(d * factor) / factor;
            if ((d % 0.01) != 0.0)
            {
                System.out.println(d + " " + (d % 0.01));
                errors++;
            }
        }
        System.out.println(count + " trials " + errors + " errors");
    }
}
0 голосов
/ 26 сентября 2011

Обычно я не округляю само число , а округляю строковое представление числа, когда мне нужно его отобразить, потому что обычно это значение имеет значение дисплея, которое нуждается в округлении (хотя это может и не быть верно в ситуациях, и, возможно, у вас, но вы должны уточнить это, если так). Таким образом, мой номер сохраняет свою точность, но его отображение упрощается и его легче читать. Для этого можно использовать объект DecimalFormat, например, инициализированный строкой «0,000» (new DecimalFormat("0.000")), или использовать String.format("%.3f", myDouble), или несколькими другими способами.

Например:

// yeah, I know this is just Math.PI.
double myDouble = 3.141592653589793;
DecimalFormat myFormat = new DecimalFormat("0.000");
String myDoubleString = myFormat.format(myDouble);
System.out.println("My number is: " + myDoubleString);

// or you can use printf which works like String.format:
System.out.printf("My number is: %.3f%n", myDouble);
...