Ich habe vor kurzem in einem Projekt mit Sonar angefangen, und ich habe eine PMD-Regel über den Konstruktor new BigDecimal(double val)
gebrochen. Wenn ich die Java-Dokumentation lese, fand ich, dass BigDecimal (double val) etwas unvorhersehbar ist und dass ich new BigDecimal(String val)
verwenden sollte, was vorhersehbar ist.
Hier ist, was javadoc für BigDecimal
public BigDecimal(double val)
sagt:
Übersetzt ein Double in ein BigDecimal, welches die genaue Dezimalzahl ist Darstellung des binären Fließkommawertes des Doppelpunktes. Die Skala des zurückgegebenen BigDecimal ist der kleinste Wert, so dass (10scale × val) ist eine ganze Zahl.
Anmerkungen:
Die Ergebnisse dieses Konstruktors können etwas unvorhersehbar sein. Ein könnte annehmen, dass das Schreiben von
new BigDecimal(0.1)
in Java ein erstelltBigDecimal
, was exakt gleich 0,1 ist (ein unskalierter Wert von 1, mit einer Skala von 1), aber es ist tatsächlich gleich 0.1000000000000000055511151231257827021181583404541015625. Dies liegt daran, dass 0.1 nicht genau als ein Doppel dargestellt werden kann Materie als binärer Bruchteil beliebiger endlicher Länge). Also der Wert das dem Konstruktor übergeben wird, ist nicht genau gleich 0,1, Erscheinungen ungeachtet.Der String-Konstruktor hingegen ist perfekt vorhersehbar: write
new BigDecimal("0.1")
erstellt einBigDecimal
was ist genau gleich 0,1, wie man es erwarten würde. Daher ist es allgemein empfohlen, dass stattdessen der String-Konstruktor verwendet wird eins.Wenn ein double als Quelle für
BigDecimal
verwendet werden muss, beachten Sie Folgendes Dieser Konstruktor bietet eine genaue Konvertierung. es gibt nicht die Das gleiche Ergebnis wie das Konvertieren des Double in einen String mit demDouble.toString(double)
Methode und dann mit derBigDecimal(String)
Konstruktor. Um dieses Ergebnis zu erhalten, verwenden Sie die statischevalueOf(double)
Methode.
Warum existiert dieser Konstruktor wirklich? Ist%% genug für diese Angelegenheit? Wann sollte ich den new BigDecimal(String val)
-Konstruktor verwenden?
Warum existiert dieser Konstruktor wirklich?
Er konvertiert den tatsächlich dargestellten Wert von double
in ein BigDecimal. Der ganze Sinn von BigDecimal ist es, so viel Präzision wie möglich zu geben, und genau das macht dieser Konstruktor.
Wenn Sie den Wert, den Sie mit einer kleinen Rundung erhalten würden, verwenden möchten, verwenden Sie% /% %Vor%
druckt
%Vor%Wann sollte ich den neuen Konstruktor BigDecimal (double val)
verwenden?
Wenn Sie wissen möchten, dass der Wert Double.toString(double)
wirklich darstellt. Sie können Ihre eigene Rundung nach Bedarf anwenden.
Wenn Sie double
verwenden, sollten Sie immer eine sinnvolle Rundung anwenden. Aber wenn Sie das getan haben, werden Sie möglicherweise BigDecimal nicht mehr benötigen. ;)
Wenn Sie bereits mit einem double
-Wert als Daten beginnen, haben Sie diese Präzisierung bereits verloren. Wenn Sie es nicht benötigen, müssen Sie es in String
für BigDecimal
konvertieren, um es zurück zu konvertieren.
Und vielleicht brauchen Sie auch manchmal diesen Wert.
When should I use the new BigDecimal(double val) constructor?
Vorzugsweise - nirgendwo.
Wenn Sie bereit sind, mit BigDecimals zu spielen, bedeutet die Verwendung von Konstruktor mit Double, alle Vorteile der exakten Zahlenpräsentation zu verlieren.
Why does this constructor really exists?
Weil Sie manchmal nur Double haben, das Sie in BigDecimal übersetzen möchten. Sie zu zwingen, .toString()
dazwischen zu verwenden, wäre einfach albern;)
Ich wollte etwas kommentieren, aber ich kann mir nicht vorstellen, wie man "Code" in einen Kommentar schreibt, also antworte ich:
double val = 0.1; // this is not 0.1, but an approximination as pointed out in other answers.
BigDecimal biggy = new BigDecimal(val); // this variable conatains the "same" value as val does, however it is not 0.1, but as pointed out in other answers: 0.100000000000000005551115123
Also, in dem hier aufgelisteten Fall, wo Sie die volle Kontrolle über den Quellcode haben, sollten Sie das val als 'String val="0.1"'
schreiben Der Konstruktor BigDecimal(double val)
ist jedoch nützlich, wenn Sie binäre Doubles aus einer Datei lesen. Offensichtlich werden Sie in fast allen Fällen BigDecimals, die genau die gleichen sind wie die "Doppelgänger"
Unvorhersehbar? Ich stimme nicht zu.
%Vor%Schlüssel zum Verständnis:
%Vor% Wenn Sie wirklich "0.1" meinten, dann verwenden Sie den String-Konstruktor =). Wenn Sie aber bereits ein double
haben, dann ist dieses Double nicht "0.1".
Der von Ihnen zitierte JavaDoc sagt:
Wenn ein Double als Quelle für ein BigDecimal verwendet werden muss, beachte das Dieser Konstruktor bietet eine exakte Konvertierung;
Ich kann nicht sehen, wie eine genaue Umwandlung "unvorhersehbar" ist, und ich bin sehr dafür, das Wort "müssen" aus diesem Zitat zu entfernen.
Am Ende des Tages arbeiten beide Konstruktoren wie beabsichtigt. Wenn Sie String "0.1" haben, konvertiert BigDecimal (String) diesen Wert genau. Wenn Sie eine doppelte 0.1 haben, konvertieren Sie BigDecimal (double) diesen Wert genau.
Tags und Links java