# wiedermal ein kleines Problem mit BigDecimal



## sence (6. Mai 2010)

Hallo Forum,

Wollte mich nun mit BigDecimal auseinander setzten und hab gerade nicht so ganz den durchblick :/
es gibt zwar einige treffer in google aber hab gerade nen "hänger"

Frage 1)
aufgrund von ungenauigkeit ist float und double in ERC (Warenwirtschaft / Buchhaltung verboten)
und es sollte big decimal genommen werden.

so beispiel 1:
		BigDecimal a = new BigDecimal(1.0);	
		BigDecimal b = new BigDecimal(0.9);			
		System.out.print(a.subtract(b));
0.09999999999999997779553950749686919152736663818359375


setzte ich diese in Anführungszeichen :
                          BigDecimal a = new BigDecimal("1.0");	
		BigDecimal b = new BigDecimal("0.9");			
		System.out.print(a.subtract(b));
0.1 -> ist korrekt.

Wieso das?

dann nun das eigentlich Problem:
wie würdet ihr z.b diese Methode schreiben:


```
public double getGesamtWert() {
    	RechnungsArtikelTool rat = null;
    	double gesamt = 0;
    	for(int i = 0; i < VAM.ArtTabelle.size(); i++) {
    		rat = (RechnungsArtikelTool) VAM.ArtTabelle.get(i);
    		double menge = rat.Menge;
    		double mwst = rat.Mwst;
    		double vk = rat.Vk;
    		double tmp = vk * menge * (1. + mwst);		
    		gesamt += Math.round(tmp * 100) / 100.;  
    	}   		
    	return gesamt;
    }
```
Rat = das Artikel Objekt (menge, ek, vk ,mwst und co)
ich habe bis jetzt nur notbedürftig mit double gemacht, jedoch direkt geroundet und mit 100 multipliziert und durch /100. geteilt.
Es funktioniert soweit aber ab ca 10.000.000,00 gibt er mir den Wert mit E5 (wie heisst das nochmal :O) zurück.

ich will es aber nun richtig machen, deswegen please help, 
das Problem ist bei BigDecimal dass ich nur das korrekte Ergebniss bekomme wenn diese in "" stehen, aber wie gehts mit der Variablen auslesung?

Vielen Dank!!!!!:rtfm:


----------



## gman (6. Mai 2010)

Hi,

guck mal in die Java-API-Doku. Dort werden beide Konstruktoren von BigDecimal beschrieben:

BigDecimal(double val) -> dein erstes Beispiel

BigDecimal(String val) -> dein zweites Beispiel

Kurz: Wenn du den Konstruktor mit einem String nimmst berücksichtigt er die Anzahl der Nachkommastellen. Wenn du den Konstruktor mit double nimmst:



> The results of this constructor can be somewhat unpredictable.



Daher die verschiedenen Ergebnisse.


----------



## sence (6. Mai 2010)

also immer so basteln die Berechnungen ?


```
BigDecimal bd2 = BigDecimal.valueOf(rs.getDouble(1)); // bzw rat.vk
		BigDecimal bd3 = BigDecimal.valueOf(rs.getDouble(2)); // bzw rat.menge
		BigDecimal bd4 = BigDecimal.valueOf(rs.getDouble(3)); // bzw rat.mwst
		System.out.print(dann hier die berechnung);
```


----------



## JohannisderKaeufer (6. Mai 2010)

:applaus::applaus::applaus::applaus::applaus::applaus::applaus::applaus::applaus::applaus:
Genau so!

:applaus::applaus::applaus::applaus::applaus::applaus::applaus::applaus::applaus::applaus:


----------



## sence (12. Mai 2010)

Hey,

nächste Frage dazu, nun wollte ich es implementieren hab aber noch irgendwie schwierigkeiten :/


```
BigDecimal menge = BigDecimal.valueOf(1);    		
		BigDecimal mwst = BigDecimal.valueOf(1.00);
		mwst.add(BigDecimal.valueOf(0. + 19));
		BigDecimal ek = BigDecimal.valueOf(10);		
		BigDecimal divsize = BigDecimal.valueOf(100.0);
		BigDecimal result = menge.multiply(ek);
		if(mwst.doubleValue() > 1.00) {
			result.multiply(mwst);
		}
		System.out.println(result + " mwst " + mwst);
```

Ergebniss = 10 mwst 1.0

Kurze Info dazu:
Der User gibt nur die Prozentzahl ein z.b 19, deshalb (0. + 19)


ich möchte die menge * ek. Das geht.
Dann: die Mehrwertsteuer generieren (ergibt jedoch 1, anstelle von 1.19)

Und nur, wenn die Mwst größer als 1 ist ( preis * 0 = 0, deshalb 1 *g*) soll diese berechnet werden.
Er hakt aber schon bei 1 + 0.19 :/

Nebenfrage:
Da alle Artikel nur 2 nachkommastellen haben, wieso ist double nicht angebracht ?

dankeeeee


----------



## JohannisderKaeufer (12. Mai 2010)

Wie wäre es mit einem Test?


```
package bigdecimals;

import java.math.BigDecimal;
import org.junit.Test;
import static org.junit.Assert.*;

public class MainTest {

    @Test
    public void testBerechneMwst() {
        System.out.println("berechneMwstFaktor");
        String benutzereingabe = "19";
        BigDecimal result = Main.berechneMwstFaktor(benutzereingabe);
        assertEquals(new BigDecimal("1.19"), result);
    }

    @Test
    public void testBerechnePreis() {
        System.out.println("berechne");
        BigDecimal menge = new BigDecimal(1);
        BigDecimal preis = new BigDecimal(10);
        String mwst = "19";
        BigDecimal result = Main.berechnePreis(menge, preis, mwst);
        assertEquals(new BigDecimal("11.90"), result);
    }
}
```

und dann dem Versuch einer Implementierung


```
package bigdecimals;

import java.math.BigDecimal;

public class Main {

    public static BigDecimal berechneMwstFaktor(String benutzereingabe) {
        if (benutzereingabe.equals("")) {
            return BigDecimal.ONE;
        }
        return new BigDecimal(benutzereingabe).divide(new BigDecimal(100)).add(BigDecimal.ONE);
    }

    public static BigDecimal berechnePreis(
            BigDecimal menge,
            BigDecimal preis,
            String mwst) {
        return menge.multiply(preis).multiply(berechneMwstFaktor(mwst));
    }

    public static void main(String[] args) {
        System.out.println(berechnePreis(
                new BigDecimal(10),
                new BigDecimal(1),
                "19"));
    }
}
```


----------

