Quelqu'un peut-il recommander un moyen efficace de déterminer si une BigDecimal
est une valeur entière au sens mathématique?
À l'heure actuelle, j'ai le code suivant:
private boolean isIntegerValue(BigDecimal bd) {
boolean ret;
try {
bd.toBigIntegerExact();
ret = true;
} catch (ArithmeticException ex) {
ret = false;
}
return ret;
}
... mais souhaiterait éviter la surcharge de création d'objet si nécessaire. Auparavant, j'utilisais bd.longValueExact()
, ce qui éviterait de créer un objet si BigDecimal
utilisait sa représentation compacte en interne, mais échouait évidemment si la valeur était trop grande pour tenir dans un long.
Toute aide appréciée.
Selon la source/l'utilisation de vos valeurs BigDecimal
, il peut être plus rapide de vérifier si l'échelle <= 0 en premier. Si c'est le cas, il s'agit certainement d'une valeur entière au sens mathématique. Si elle est> 0, alors pourrait rester une valeur entière et le test le plus coûteux sera nécessaire.
EDIT: À partir de Java 8, stripTrailingZeroes () représente maintenant zéro
BigDecimal stripTrailingZeros ne fonctionne pas pour zéro
Alors
private boolean isIntegerValue(BigDecimal bd) {
return bd.stripTrailingZeros().scale() <= 0;
}
Est parfaitement bien maintenant.
Si vous utilisez les solutions scale()
et stripTrailingZeros()
mentionnées dans certaines réponses, vous devez faire attention à zéro. Zéro est toujours un entier quelle que soit son échelle, et stripTrailingZeros()
ne modifie pas l'échelle d'un BigDecimal zéro.
Donc, vous pourriez faire quelque chose comme ça:
private boolean isIntegerValue(BigDecimal bd) {
return bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0;
}
Divisez le nombre par 1 et vérifiez s'il en reste un. Tout nombre entier doit toujours avoir un reste de 0 lorsqu'il est divisé par 1.
public boolean isWholeNumber(BigDecimal number) {
return number.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0;
}
Vous pouvez utiliser ceci (en résumant simplement à partir d'autres réponses):
private boolean isIntegerValue(BigDecimal bd) {
return bd.stripTrailingZeros().scale() <= 0;
}
Cela peut être fait de la même manière que quelqu'un vérifierait si un double est un entier, en effectuant% 1 == 0. Voici comment cela chercherait une valeur BigDecimal.
public static boolean isIntegerValue(BigDecimal bd){
return bd.remainder(new BigDecimal("1")).compareTo(BigDecimal.ZERO) == 0;
}
Ceci est le plus propre que je suis venu avec.
public static boolean isWhole(BigDecimal bigDecimal) {
return bigDecimal.setScale(0, RoundingMode.HALF_UP).compareTo(bigDecimal) == 0;
}