Zur Zeit habe ich diese Methode:Wie überprüft man, ob ein Double maximal n Dezimalstellen hat?
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 nicht für checkDecmialPlaces(649632196443.4279, 4)
wahrscheinlich, weil ich auf eine Basis 2 Nummer Basis 10 Mathematik zu tun.
Wie also kann diese Überprüfung korrekt durchgeführt werden?
Ich dachte daran, eine String-Darstellung des doppelten Wertes zu bekommen und dann das mit einem Regexp zu überprüfen - aber das fühlte sich komisch an.
EDIT: Danke für alle Antworten. Es gibt Fälle, in denen ich eine doppelte bekommen wirklich und für jene Fälle, die ich umgesetzt folgendes:
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;
}
ich die round
zu einer Verkürzung geändert. Scheint, dass die in round
vorgenommene Berechnung die Ungenauigkeit zu sehr erhöht. Zumindest im fehlgeschlagenen Testfall.
Wie einige von euch wies darauf hin, wenn ich auf die ‚echten‘ String-Input bekommen konnte ich Ich habe BigDecimal
zu überprüfen und so getan verwenden sollten:
BigDecimal decimal = new BigDecimal(value);
BigDecimal checkDecimal = decimal.movePointRight(decimalPlaces);
return checkDecimal.scale() == 0;
Der double
Wert ich kommt von der Apache POI-API, liest Excel-Dateien. Ich habe ein paar Tests gemacht und herausgefunden, dass, obwohl die API double
Werte für numerische Zellen zurückgibt, kann ich 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 gilt auch für die Werte, die nicht funktioniert im Binärformat genau dargestellt werden.
„richtig“ Exponent verhören bedeutet nicht viel hier. Ihre zufälligen Dezimalzahlen haben keine genauen binären Darstellungen. Sie suchen nach einer Dezimalzahl, die "nahe genug" ist, so dass Leute die Dezimalversion des binären Werts mögen. Wie nah ist nahe genug? –