2016-08-30 5 views
-1

In einer Java-Anwendung ich einen Komponententest, die die folgende Situation enthält:Warum dieser Vergleich zwischen 2 BigDecimal fehlschlagen?

BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal(2.85000); 
BigDecimal rendimentoLordoProvvisiorioDB = null; 

rendimentoLordoProvvisiorioDB = pucManager.getRendimentoLordoProvvisorio(date); 

assertTrue(rendimentoLordoProvvisiorioExpected.compareTo(rendimentoLordoProvvisiorioDB) == 0); 

der Wert des rendimentoLordoProvvisiorioExpected Variable manuell 2,85000 und der erhaltene Wert rendimentoLordoProvvisiorioDB setted ist 2,85000 .

Das Problem ist, dass, wenn ich tue, um diesen Vergleich in den assertTrue() JUnit Funktion

assertTrue(rendimentoLordoProvvisiorioExpected.compareTo(rendimentoLordoProvvisiorioDB) == 0); 

es scheitern, weil die rendimentoLordoProvvisiorioExpected2,850000000000000088817841970012523233890533447265625 und nicht 2,85000 (als setted zu sein scheint).

Warum? Wie kann ich den vorherigen Code ändern, um rendimentoLordoProvvisiorioExpected auf den erwarteten Wert 2.85000 zu setzen?

+3

Sie initialisieren "RendimentoLordoProvvisiorioExpected" mit einem Double, das nicht präzise ist. Versuchen Sie stattdessen, es mit einem String zu initialisieren. – hotzst

+1

Ich frage mich, warum Sie nicht einmal gelesen haben, was der JavaDoc von ['BigDecimal (double)'] (https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#BigDecimal -doppelt-). Es sagt Ihnen, dass "double" nicht genau ist, was Sie stattdessen verwenden sollten. – Tom

Antwort

4

Da Sie das BigDecimal mit einem Fließkommawert initialisieren, indem Sie den Konstruktor mit einem Double aufrufen. Doppel sind Gleitkommazahlen. Verwenden Sie einen String:

BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal("2.85000"); 

Sie sollten die documentation of BigDecimal regarding calling the double version of the constructor lesen.

Wenn Sie ein BigDecimal-Objekt verwenden, konvertieren Sie einen Gleitkommawert der Basis 2 in eine Gleitkommazahl der Basis 10. Es gibt keine perfekte Basis zwei Floating-Point-Darstellung der Zahl 2,85, scheint die beste Annäherung eine Zahl nahe zu sein:

>>> decimal.Decimal(2.85) 
Decimal('2.850000000000000088817841970012523233890533447265625') 

Sie sollten What Every Programmer Should Know About Floating-Point Arithmetic mehr über Floating-Point, zum Beispiel lesen.

6

Verwenden Sie BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal("2.85000"); anstelle von BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal(2.85000); Was Sie getan haben, war ein BigDecimal aus einem Doppel zu bauen, und Doppel sind nicht präzise.

+0

Was meinst du, dass doppelte Note genau ist? Es ist eine Annäherung oder was? – AndreaNobili

+1

@AndreaNobili Research .... http://stackoverflow.com/questions/588004/is-floating-point-math-broken – Tom

+0

Weil Sie den BigDecimal Konstruktor mit einem Doppelklick aufrufen. Doppel sind Gleitkommazahlen. Deshalb sollten Sie eine Zeichenfolge verwenden. – vz0

Verwandte Themen