float Berechnung: Ergebnis ohne wissenschaftliche Notation

holeai

Neues Mitglied
Hallo zusammen

Ich habe folgendes Problem und bis jetzt noch nirgends etwas gefunden, was wirklich funktioniert hätte.

Ich habe einen Beträge die ich mit einer Zinsrate multiplizieren möchte. Das ganze läuft in einer Schleife für mehre Beträge und Zinsraten ab. Bei den meisten funktioniert es auch ohne Probleme, aber bei zwei Beträgen erhalte ich als Ergebnis immer den Betrag als wissenschaftliche Notation:

als beispiel:

float ir = new Float(1.0015);
float amount = new Float(9987652);


float total = ir * amount;


Dabei kommt dann immer 1.0002634E7 raus...

wenn der Beträg z.b. 5648756 ist, funktioniert es noch korrekt.
Einige Beiträge dazu empfehlen Umwandlung in BigDecimal, aber dann verliere ich die Kommastellen. Ich weiss, dass Float sowieso ungenau ist, das spielt aber hier keine Rolle. Ich benötige einfach den Betrag auf zwei Kommastellen gerundet und brings irgendwie nicht hin.

Habt ihr eine Idee ?
 
Beispiel basierend auf: https://stackoverflow.com/questions/5195837/format-float-to-n-decimal-places#answer-37878834
Java:
import java.math.*;
import java.text.*;
public class FloatFormat {
  public static void main(String[] args) {
    float v = 1.0002634E7f;
    NumberFormat f = NumberFormat.getInstance();
    /* Exakt zwei Nachkommastellen anzeigen */
    f.setMaximumFractionDigits(2);
    f.setMinimumFractionDigits(2);
    /* Und kaufmännisch runden */
    f.setRoundingMode(RoundingMode.HALF_UP);
    /* Willst du Tausendertrennzeichen? */
    f.setGroupingUsed(true);
    String str = f.format(v);
    System.out.println(str);
    // -> 10.002.634,00
  }
}
Bedenke, dass dein Problem nur die Formatierung von Fließkommawerten in eine Zeichenkette ist. Die Fließkommawerte selber sind einfach unformatierte IEEE-754 Werte an sich. Es kommt nur darauf an, wie du diese Werte als Strings formatierst/ausgibst. Wenn du aktuell z.B. einfach nur System.out.println(v); verwendet hast, legt Float.toString(v) intern fest, wie der Wert in eine Zeichenkette formatiert werden soll.
 
Das Problem ist, dass dies die nachkommastellen abschneidet. .0000 etc.
88'660'144.000.
entweder funktioniert es nach dem Komma, oder vor, aber beides geht nicht
 
Gib bitte ein MVCE für einen Fall, der nicht funktioniert. Wo wird was abgeschnitten? Wann wird was abgeschnitten? Das genannte Beispiel mit dem NumberFormat funktioniert definitiv.
 
Okay, ich ahne schon, wo hier das Problem ist. Der Wert 88.660.144,230 (zum Beispiel) ist in IEEE-754 32-bit float nicht mehr repräsentierbar. Er benötigt einfach zu viele signifikante Stellen (in der Mantisse) und somit werden schon im Wert selber die niedrigstwertigen Stellen abgeschnitten/gerundet. Deshalb wird auch bei der Formatierung zum String aus ,230 dann ,000.
Deine erste Ausweichmöglichkeit wäre, double statt float zu nehmen. Hier kommst du dann bei ca. 15-16 signifikanten Stellen in Probleme.
Auf Nummer sicher gehst du, wenn du BigInteger (z.B. immer in Cents rechnen) oder BigDecimal für die ganze Arithmetik (und nicht nur für die finale Formatierung zum String) verwendest.
 

Zurück
Oben