Określenie ilośći miejsc po przecinku

0

Czy jest możliwość określenia ile miejsc po przecinku ma dany double? Chodzi mi o zaokrąglenie liczb mających więcej niż 4 miejsca po przecinku, ale pozostawienie w aktualnej formie tych krótszych.

0

Tą metodę znalazłem tutaj na forum, to nie mój pomysł.

       public double zaokraglanieDouble(double val) {
        long factor = (long) Math.pow(10, ileLiczbPoPrzecinku);
        val = val * factor;
        long tmp = Math.round(val);
        return (double) tmp / factor;
    }

ileLiczbPoPrzecinku - tutaj należy wpisać cyfrę określającą ilość miejsc po przecinku
Pozdrawiam TJ

0

Określenie precyzji double'a w systemie dziesiętnym to bardzo ciekawy problem. Najpopularniejsza implementacja tej funkcji ma około 4 tysięcy linii (http://www.netlib.org/fp/dtoa.c), jej trochę okrojonej wersji używa np. Python.

A twój konkretny problem możesz rozwiązać poprzez zastosowanie String.format z %.4f i stripowaniem ewentualnych zer z końca.

0

A nie dosc, ze to problem ciekawy, to i rozlegly. Ja ostatnio zaokraglam w oparciu o BigDecimal:

public double round(double value, int places) {
        if (places < 0) throw new IllegalArgumentException();
        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(places, RoundingMode.HALF_UP);
        return bd.doubleValue();
    }
 
0

Warto by jeszcze ustalić czego autor potrzebuje:

  • zaokrąglenia liczby w pamięci,
  • wypisania liczby w żądanej postaci.
    @Rev podał sposób na drugie, a @Gjorni na pierwsze.
0

Jeszcze raz odpowiadając na Twoje pytanie Autorze - tak, można określić ile miejsc dziesiętnych ma dana liczba zmiennoprzecinkowa. Jednak jest tutaj mały haczyk. Mając np. double a = 2.10000, Java widzi wartość zmiennej a identycznie, jak wartość 2.1. Są one kodowane identycznie. Dlatego możemy jedynie określić liczbę miejsc dziesiętnych, które są niezbędne do wyrażenia danej liczby zmiennoprzecinkowej. Od tego momentu robi się już łatwiej, bo w takiej sytuacji wystarczy skorzystać np. z Double.toString() i obliczyć ilość znaków po kropce:

public class AK47 {
    public static void main(String[] args) {

        double a = 2.34673456;

        if (countDecimalPlaces(a) > 4) {
            System.out.println(round(a, 4));
        } else {
            System.out.println(a);
        }
    }

    public static int countDecimalPlaces(double value) {
        String[] doubleToString = Double.toString(value).split("\\.");
        int numberOfDecimals = doubleToString[1].length();
        return numberOfDecimals;
    }

    public static double round(double value, int places) {
        if (places < 0) throw new IllegalArgumentException();
        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(places, RoundingMode.HALF_UP);
        return bd.doubleValue();
    }
}
0

Jeśli chodzi o formatowanie bez zer na końcu to jest kilka rozwiązań:
http://stackoverflow.com/questions/703396/how-to-nicely-format-floating-numbers-to-string-without-unnecessary-decimal-0

Dlaczego double nie stosuje się do obsługi kwot:
http://www.drdobbs.com/jvm/javas-floating-point-imprecision/240168744

Więcej o liczbach zmienno-przecinkowych:
http://introcs.cs.princeton.edu/java/91float/

2
String.format("%.4f", number).replaceAll("\\.?0+$", "")

1 użytkowników online, w tym zalogowanych: 0, gości: 1