J'ai essayé ce qui suit,
double doubleVal = 1.745;
double doubleVal1 = 0.745;
BigDecimal bdTest = new BigDecimal( doubleVal);
BigDecimal bdTest1 = new BigDecimal( doubleVal1 );
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:"+bdTest); //1.75
System.out.println("bdTest1:"+bdTest1);//0.74 problemmmm ????????????
mais obtenu des résultats étranges. Pourquoi?
Ne construisez jamais BigDecimals à partir de flottants ou de doubles. Construisez-les à partir d'ints ou de chaînes. flotte et double la précision perdue.
Ce code fonctionne comme prévu (je viens de changer le type de double en String):
public static void main(String[] args) {
String doubleVal = "1.745";
String doubleVal1 = "0.745";
BigDecimal bdTest = new BigDecimal( doubleVal);
BigDecimal bdTest1 = new BigDecimal( doubleVal1 );
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:"+bdTest); //1.75
System.out.println("bdTest1:"+bdTest1);//0.75, no problem
}
double doubleVal = 1.745;
double doubleVal1 = 0.745;
System.out.println(new BigDecimal(doubleVal));
System.out.println(new BigDecimal(doubleVal1));
les sorties:
1.74500000000000010658141036401502788066864013671875
0.74499999999999999555910790149937383830547332763671875
Ce qui montre la valeur réelle des deux doubles et explique le résultat obtenu. Comme l'ont fait remarquer d'autres personnes, n'utilisez pas le constructeur double (à l'exception du cas spécifique dans lequel vous souhaitez voir la valeur réelle d'un double).
En savoir plus sur la double précision:
Utilisez BigDecimal.valueOf(double d)
au lieu de new BigDecimal(double d)
. Le dernier a des erreurs de précision par float et double.
Cela vous donnera peut-être un indice sur ce qui ne va pas.
import Java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal bdTest = new BigDecimal(0.745);
BigDecimal bdTest1 = new BigDecimal("0.745");
bdTest = bdTest.setScale(2, BigDecimal.ROUND_HALF_UP);
bdTest1 = bdTest1.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("bdTest:" + bdTest);
System.out.println("bdTest1:" + bdTest1);
}
}
Le problème est que votre entrée (un double x=0.745;
) Ne peut pas représenter 0,745 exactement. En fait, il enregistre une valeur légèrement inférieure. Pour BigDecimals
, il est déjà inférieur à 0,745, donc il est arrondi ...
Essayez de ne pas utiliser les constructeurs BigDecimal(double/float)
.
Pour votre intérêt, faire de même avec double
double doubleVal = 1.745;
double doubleVal2 = 0.745;
doubleVal = Math.round(doubleVal * 100 + 0.005) / 100.0;
doubleVal2 = Math.round(doubleVal2 * 100 + 0.005) / 100.0;
System.out.println("bdTest: " + doubleVal); //1.75
System.out.println("bdTest1: " + doubleVal2);//0.75
ou juste
double doubleVal = 1.745;
double doubleVal2 = 0.745;
System.out.printf("bdTest: %.2f%n", doubleVal);
System.out.printf("bdTest1: %.2f%n", doubleVal2);
les deux imprimer
bdTest: 1.75
bdTest1: 0.75
Je préfère garder le code aussi simple que possible. ;)
Comme le note @mshutov, vous devez ajouter un peu plus pour vous assurer qu'une demi-valeur est toujours arrondie. C'est parce que des nombres comme 265.335
sont un peu moins qu’ils n’apparaissent.