Question

Quelqu'un peut-il recommander une façon de déterminer si une est une valeur BigDecimal entier dans le sens mathématique efficace

À l'heure actuelle je le code suivant:

private boolean isIntegerValue(BigDecimal bd) {
    boolean ret;

    try {
        bd.toBigIntegerExact();
        ret = true;
    } catch (ArithmeticException ex) {
        ret = false;
    }

    return ret;
}

... mais je voudrais éviter la création d'objets en tête si nécessaire. Auparavant, j'utilisais qui éviterait bd.longValueExact() créer un objet si l'utilisait sa <=> représentation compacte en interne, mais serait évidemment échouer si la valeur était trop grand pour tenir dans une longue.

Toute aide appréciée.

Était-ce utile?

La solution

En fonction de la source / l'utilisation de vos valeurs qu'il pourrait BigDecimal être plus rapide pour vérifier si l'échelle <= 0 premier. Dans ce cas, il est certainement une valeur entière dans le sens mathématique. Si elle est> 0, il peut toujours être une valeur entière et le test plus cher serait nécessaire.

Autres conseils

EDIT: Comme de Java 8, stripTrailingZeroes () représente désormais zéro

BigDecimal stripTrailingZeros ne fonctionne pas pour zéro

private boolean isIntegerValue(BigDecimal bd) {
  return bd.stripTrailingZeros().scale() <= 0;
}

est parfaitement bien maintenant.


Si vous utilisez la solution scale() et mentionnée dans stripTrailingZeros() quelques-unes des réponses que vous devez prêter attention à zéro. Zero est toujours un entier, peu importe quelle échelle il a, et ne modifie pas <=> l'échelle d'un BigDecimal zéro.

Alors vous pouvez faire quelque chose comme ceci:

private boolean isIntegerValue(BigDecimal bd) {
  return bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0;
}

Diviser le nombre de 1 et pour vérifier un reste. Tout 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 ce (juste récapitulant d'autres réponses):

private boolean isIntegerValue(BigDecimal bd) {
  return bd.stripTrailingZeros().scale() <= 0;
}

Un possiblity devrait être de vérifier si échelle () est nulle ou négative. Dans ce cas, le BigDecimal ne devrait pas avoir de chiffres après la virgule et le nombre doit être un entier mathématique si je comprends bien votre question.

Mise à jour : Si elle est positive, il pourrait encore être un entier, mais vous ne pouvez pas épargner créations d'objets supplémentaires pour des contrôles approfondis dans ce cas. Un exemple pour un tel cas est donnée à la stripTrailingZeros () méthode javadoc (merci Joachim pour l'indice dans sa réponse).

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;
}

Cela peut se faire de la même façon que quelqu'un vérifier si un double est un entier, effectuant% 1 == 0. Voici comment il rechercherait une valeur BigDecimal.

public static boolean isIntegerValue(BigDecimal bd){
  return bd.remainder(new BigDecimal("1")).compareTo(BigDecimal.ZERO) == 0;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top