2009-05-25 20 views
14

J'essaie de calculer un pourcentage "facteur". C'est-à-dire, donné 20%, le convertir en 0.2 (mon intention est de plus tard multiplier les valeurs par cela et obtenir les 20% des valeurs).Java, BigDecimal. Problèmes avec la division

Quoi qu'il en soit, la question est liée à ce morceau de code:

public static void main(String[] args) { 
    int roundingMode = BigDecimal.ROUND_FLOOR; 
    BigDecimal hundred = new BigDecimal("100"); 
    BigDecimal percentageFactor = null; 
    BigDecimal percentage = new BigDecimal("20"); 
    BigDecimal value = new BigDecimal("500"); 
    percentageFactor = percentage.divide(hundred, roundingMode); 
    float f = percentage.floatValue()/hundred.floatValue(); 
    f = value.floatValue() * f; 
    BigDecimal aux = value.multiply(percentageFactor); 
    System.out.println("factor:"+percentageFactor.toString()); 
    System.out.println("final falue:"+aux.toString()); 
    System.out.println("Float Value:"+f);  
} 

J'attends le résultat de cela est quelque chose comme:

factor: 0.2 
final value: 100 
float value: 100 

mais percentage.divide(hundred, roundingMode); est de retour à zéro, un par conséquent je reçois:

factor:0 
final falue:0 
Float Value:100.0 

Qu'est-ce que je fais mal? Comment puis-je diviser correctement deux grandes décimales? Au fait, j'utilise BigDecimal parce que je calcule des pourcentages monétaires, donc je veux contrôler l'arrondi.

Répondre

9

L'échelle de new BigDecimal("20") est nul parce que vous avez pas de point décimal là-dedans. Cela signifie que votre percentage.divide(hundred, BigDecimal.ROUND_FLOOR) produira zéro (c'est effectivement int(20/100) ou 0).

Si vous voulez vraiment faire des choses fractionnaires, utilisez new BigDecimal("20.00") afin que l'échelle soit définie correctement, ou utilisez l'un des autres constructeurs pour définir l'échelle spécifiquement.

est ici la sortie de ce simple changement de 20-20.00, avec votre misteak de spellink :-)

factor:0.20 
final falue:100.00 
Float Value:100.0 
13

Je pense que la meilleure solution consiste à définir l'échelle demandée lors de la division: Dans ce cas, peut-être 2.

BigDecimal hundred = new BigDecimal(100); 
    BigDecimal percentage = new BigDecimal(20); 
    BigDecimal value = new BigDecimal(500); 
    BigDecimal percentageFactor = 
       percentage.divide(hundred,2, BigDecimal.ROUND_HALF_UP); 

    value = value.multiply(percentageFactor); 
    System.out.println("final value:"+ value); 

valeur finale 100,00

(utilise l'Multiplication échelle des facteurs (0 + 2), mais il peut b e spécifié aussi.)

J'utiliserais HALF_UP pour la comptabilité (dans ma législation) ou EVEN (pour les statistiques) pour le mode d'arrondi.

0

float a seulement 6 chiffres de précision et n'est presque jamais un bon choix, je vous suggère d'utiliser double à la place. (ou BigDecimal peut être meilleur dans certains cas)

+0

Si vous voulez contrôler l'arrondi, vous ne devriez pas utiliser de nombres à virgule flottante, ni flotter ni doubler. Stick avec BigDecimal. – markusk

+0

Souvent, seul le résultat final doit avoir un arrondi contrôlé, donc vous avez utilisé BigDecimal juste pour arrondir le résultat (ou une méthode d'assistance simple). Cela peut être considérablement plus simple et plus rapide. –