Aller au contenu | Aller au menu | Aller à la recherche


java double précision, plutôt BigDecimal et MathContext

La précision du double peut générer des nombres extravagants... généralement cela conduit à l'utilisation de la classe BigDecimal...

public static void main(String[] args) {
		
		System.out.println("13.8 + 85.8 + 4.6 = 104.2 ?...");
		
		System.out.println("-- Avec (D/d)ouble");
		double doubleTotal = 0;
		double doubleArray[] = {13.8, 85.8, 4.6};
		for (int i = 0; i < doubleArray.length; i++) {
			doubleTotal += doubleArray[i];
			System.out.println(doubleTotal);
		}
				
		System.out.println("-- Avec BigDecimal");
		BigDecimal bigDecimalTotal = new BigDecimal(0);
		BigDecimal bigDecimalArray[] = {new BigDecimal(13.8), new BigDecimal(85.8), new BigDecimal(4.6)};
		for (int i = 0; i < bigDecimalArray.length; i++) {
//			bigDecimalTotal += bigDecimalArray[i];	// The operator += is undefined for the argument type(s) java.math.BigDecimal, java.math.BigDecimal
			bigDecimalTotal = bigDecimalTotal.add(bigDecimalArray[i]);
			System.out.println(bigDecimalTotal);
		}
		
		System.out.println("-- Avec BigDecimal - from parse string");
		BigDecimal bigDecimalStringTotal = new BigDecimal(0);
		BigDecimal bigDecimalStringArray[] = {new BigDecimal("13.8"), new BigDecimal("85.8"), new BigDecimal("4.6")};
		for (int i = 0; i < bigDecimalStringArray.length; i++) {
			bigDecimalStringTotal = bigDecimalStringTotal.add(bigDecimalStringArray[i]);
			System.out.println(bigDecimalStringTotal);
		}
		
//		http://piotrnowicki.com/2011/02/precision-and-scale-in-bigdecimal-and-mathcontext/
//		You should use new BigDecimal(String) in the first place. 
//		If you need to use double, then new BigDecimal.valueOf(double) or equivalent new BigDecimal(Double.toString(double)) should behave more expectably

		MathContext mc = new MathContext(4);
		System.out.println("-- Avec BigDecimal + MathContext(4)");
		BigDecimal bigDecimalMcTotal = new BigDecimal(0);
		BigDecimal bigDecimalMcArray[] = {new BigDecimal(13.8), new BigDecimal(85.8), new BigDecimal(4.6)};
		for (int i = 0; i < bigDecimalMcArray.length; i++) {
			bigDecimalMcTotal = bigDecimalMcTotal.add(bigDecimalMcArray[i], mc);
			System.out.println(bigDecimalMcTotal.toPlainString());
		}

		System.exit(0);

//		13.8 + 85.8 + 4.6 = 104.2 ?...
//		-- Avec (D/d)ouble
//		13.8
//		99.6
//		104.19999999999999
//		-- Avec BigDecimal
//		13.800000000000000710542735760100185871124267578125
//		99.599999999999997868371792719699442386627197265625
//		104.1999999999999975131004248396493494510650634765625
//		-- Avec BigDecimal - from parse string
//		13.8
//		99.6
//		104.2
//		-- Avec BigDecimal + MathContext(4)
//		13.80
//		99.60
//		104.2

Ressources

Exemple de résultat de division avec un MathContext.DECIMAL défini.

166.4310                                                         // MathContext.DECIMAL32	3+ 4 décimales	au total 7 digit
166.4310382495999                                       // MathContext.DECIMAL64	3+13 décimales	au total 16 digits
166.4310382495999118394932666158574   // MathContext.DECIMAL128	3+31 décimales	au total 34 digits

Si on ne définit pas le MathContexte, avec cette division au résultat infini, on prend une : java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.

Fil des commentaires de ce billet