Wie um zu überprüfen, ob Sie ein Doppel maximal n Nachkommastellen?

Derzeit habe ich diese Methode:

static boolean checkDecimalPlaces(double d, int decimalPlaces){
    if (d==0) return true;

    double multiplier = Math.pow(10, decimalPlaces); 
    double check  =  d * multiplier;
    check = Math.round(check);      
    check = check/multiplier; 
    return (d==check);      
}

Aber diese Methode fehlschlägt, für checkDecmialPlaces(649632196443.4279, 4) wahrscheinlich weil ich base 10 Mathe auf einer Basis 2 der Zahl.

Also, wie kann diese Prüfung durchgeführt werden, richtig?

Ich dachte an eine string-Darstellung der double-Wert und überprüfen Sie dann, dass mit einem regexp - aber es fühlte sich seltsam.

EDIT:
Danke für die vielen Antworten. Es gibt Fälle, wo ich wirklich eine doppelte und für diejenigen Fälle, die ich implementiert die folgenden:

private static boolean checkDecimalPlaces(double d, int decimalPlaces) {
    if (d == 0) return true;

    final double epsilon = Math.pow(10.0, ((decimalPlaces + 1) * -1));

    double multiplier = Math.pow(10, decimalPlaces);
    double check = d * multiplier;
    long checkLong = (long) Math.abs(check);
    check = checkLong / multiplier;

    double e = Math.abs(d - check);
    return e < epsilon;
}

Änderte ich die round zu einem abschneiden. Scheint, dass die Berechnung geschieht in round erhöht die Ungenauigkeit zu viel. Zumindest in der fehlerhaften Testfall.

Wie einige von Euch darauf hingewiesen, wenn ich könnte man die "echte" string-input sollte ich verwenden BigDecimal zu überprüfen und so habe ich getan:

BigDecimal decimal = new BigDecimal(value);
BigDecimal checkDecimal = decimal.movePointRight(decimalPlaces);
return checkDecimal.scale() == 0;

Den double Wert, den ich bekomme, kommt von der Apache POI API, liest excel-Dateien. Ich habe einige tests und fand heraus, dass, obwohl die API zurück double Werte für numerische Zellen, die ich bekommen kann eine genaue Darstellung, wenn ich sofort formatieren, dass double mit der DecimalFormat:

DecimalFormat decimalFormat = new DecimalFormat();
decimalFormat.setMaximumIntegerDigits(Integer.MAX_VALUE);
//don't use grouping for numeric-type cells
decimalFormat.setGroupingUsed(false);
decimalFormat.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
value = decimalFormat.format(numericValue);

Dies funktioniert auch für Werte, die nicht exakt dargestellt werden im binären format.

  • "korrekt" bedeutet nicht viel, hier. Ihre zufällige Dezimalzahlen haben keine exakte binäre Darstellungen. Sie suchen eine decimal-Zahl, die "nah genug", so dass die Menschen wie die dezimale version der binäre Wert. Wie nah ist nah genug?
InformationsquelleAutor Turismo | 2008-11-05
Schreibe einen Kommentar