2009-05-25 21 views
14

Estoy tratando de calcular un porcentaje de "factor". Es decir, dado un 20%, conviértalo en 0.2 (mi intención es luego multiplicar valores por eso y obtener el 20% de los valores).Java, BigDecimal. Problemas con la división

De todos modos, la cuestión está relacionada con este pedazo de código:

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

que sería de esperar el resultado de que esto es algo como:

factor: 0.2 
final value: 100 
float value: 100 

pero en lugar percentage.divide(hundred, roundingMode); está volviendo cero, una de ahí obtengo:

factor:0 
final falue:0 
Float Value:100.0 

¿Qué estoy haciendo mal? ¿Cómo puedo dividir dos grandes decimales correctamente?

Por cierto, estoy usando BigDecimal porque voy a calcular los porcentajes monetarios, por lo que quiero control con respecto al redondeo.

Respuesta

9

La escala de new BigDecimal("20") es cero porque no tienes punto decimal en allí. Eso significa que su percentage.divide(hundred, BigDecimal.ROUND_FLOOR) producirá cero (efectivamente es int(20/100) o 0).

Si realmente desea hacer cosas fraccionarias, use new BigDecimal("20.00") para que la escala esté configurada correctamente o use uno de los otros constructores para establecer la báscula específicamente.

Aquí está la salida a partir de simple cambio de 20 a 20.00, completa con su misteak spellink :-)

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

Creo que la mejor solución es establecer la escala solicitada al dividir: En este caso, tal vez 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); 

valor final 100,00

(Multiplicación está utilizando la escala de los factores (0 + 2), pero puede b e especificado también.)

Utilizaría HALF_UP para la contabilidad (en mi legislación) o PAR (para las estadísticas) para el modo de redondeo.

0

flotador tiene solo 6 dígitos de precisión y casi nunca es una buena opción, le sugiero que utilice el doble en su lugar. (o BigDecimal puede ser mejor en algunos casos)

+0

Si desea control sobre el redondeo, no debe utilizar números de coma flotante, ni flotante ni doble. Quédate con BigDecimal. – markusk

+0

A menudo, solo el resultado final debe tener un redondeo controlado, por lo que ha utilizado BigDecimal solo para redondear el resultado (o un simple método de ayuda). Esto puede ser significativamente más simple y rápido. –

Cuestiones relacionadas