2016-04-06 16 views
0

Ich habe versucht, mit bigdecimal in Java zu runden und habe in einen java.lang.ArithmeticException-Fehler, der nicht-beendende Dezimal-Erweiterung zeigt, ausgeführt.Rundung mit BigDecimal?

Kann jemand die Ursprünge des Fehlers erklären, wie ich zu Java ziemlich neu bin? und hilf mir mit meinem Code?

Dank

protected BigDecimal p; 
protected BigDecimal q; 
protected BigDecimal d; 
protected BigDecimal det; 
protected BigDecimal exp; 
protected int e; 

    this.p = pq.getP(); 
    this.q = pq.getQ(); 

    det = ((p.subtract(BigDecimal.ONE)).multiply(q.subtract(BigDecimal.ONE))); 
    exp = new BigDecimal(String.valueOf(e)); 

    d = (det.divide(exp).setScale(2,BigDecimal.ROUND_HALF_UP)); 

Die Variable "d" ist, wo ich die Fehler glauben entstehen wird.

+0

Seit 'e' ein' int' ist, 'neue BigDecimal (String.valueOf (e))' sollte [ 'BigDecimal.valueOf (e)'] sein (https://docs.oracle.com /javase/7/docs/api/java/math/BigDecimal.html#valueOf%28lang%29). – Andreas

+0

@Andreas ersetzt das einfach den Wert, der von exp referenziert wird, anstatt einen neuen Referenzstandort zu erstellen und zusätzlichen Speicherplatz zu belegen? – TheLiquor

+0

@TheLiquor Der Hauptgrund, da 'e' ein' int' ist, ist, dass das Konvertieren eines 'int' (oder' long') in ein BigDecimal einfach und schnell ist, aber * das 'int' zu einem String formatiert, dann * zu analysieren, dass zu einem BigDecimal ist langsam und verschwenderisch. – Andreas

Antwort

1

Sie müssen die Skalierung einstellen, wenn Sie die Teilung vornehmen.

d = det.divide(exp, 2, BigDecimal.ROUND_HALF_UP); 

Hinweis: double mit Rundung mit wahrscheinlich sauberen und weniger fehleranfällig sein.

exp = new BigDecimal(e); // does the same thing if e is an int 
+0

Ich benutze jetzt kleine Zahlen, schreibe aber eine RSA-Chiffre, so dass die verwendeten Primzahlen für die doppelte Kapazität zu groß sind, aber ich danke Ihnen sehr, sehr gut. – TheLiquor

+0

Hat sich die Frage geändert? "e" ist definiert als "int", nicht "double". Als 'int' sollten Sie ['BigDecimal.valueOf (long)'] verwenden (https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#valueOf%28long% 29). Wenn es ein "double" gewesen wäre, dann sollten Sie definitiv nicht 'new BigDecimal (double)' verwenden, sondern ['BigDecimal.valueOf (double)'] (https://docs.oracle.com/javase/7/docs /api/java/math/BigDecimal.html#valueOf%28double%29). In beiden Fällen wird 'BigDecimal.valueOf()' gegenüber 'new BigDecimal()' bevorzugt. – Andreas

+0

@TheLiquor Warum brauchen Sie 'BigDecimal' für eine RSA-Chiffre? Sie sollten nur mit ganzen Zahlen arbeiten. –