パーセンテージの「係数」を計算しようとしています。つまり、20%が与えられた場合、それを0.2に変換します(私の意図は、後で値にそれを掛けて、値の20%を取得することです)。
とにかく、質問はこのコードに関連しています:
_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);
}
_
この結果は次のようになると思います。
_factor: 0.2
final value: 100
float value: 100
_
しかし、代わりにpercentage.divide(hundred, roundingMode);
がゼロを返しているので、次のようになります。
_factor:0
final falue:0
Float Value:100.0
_
私は何が間違っているのですか? 2つの大きな小数を正しく分割するにはどうすればよいですか?
ちなみに、パーセンテージを計算するのでBigDecimal
を使用しているので、丸めを制御したいと思います。
最善の解決策は、分割するときに要求されたスケールを設定することだと思います。この場合はおそらく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);
最終値100.00
(乗算は因数(0 + 2)のスケールを使用していますが、指定することもできます。)
アカウンティング(私の法律では)にはHALF_UPを使用し、丸めモードではEVEN(統計用)を使用します。
new BigDecimal("20")
のスケールは、小数点がないためゼロです。つまり、percentage.divide(hundred, BigDecimal.ROUND_FLOOR)
はゼロを生成します(事実上int(20/100)
または_0
_です)。
分数の処理を本当に実行したい場合は、new BigDecimal("20.00")
を使用してスケールが正しく設定されるか、他のコンストラクターの1つを使用してスケールを具体的に設定します。
_20
_から_20.00
_への単純な変更からの出力は次のとおりです。
_factor:0.20
final falue:100.00
Float Value:100.0
_
floatの精度はわずか6桁であり、決して良い選択ではありません。代わりにdoubleを使用することをお勧めします。 (またはBigDecimalの方が良い場合もあります)
コードでfactor
が0.2ではなく0である理由は、
percentage
変数の暗黙のスケールは0です(スケールを指定せずに丸め番号から初期化されたBigDecimal
sのスケールは0になります)したがって、divideを呼び出すと、小数が切り捨てられ、スケールが0に維持されるため、0.2は0に切り捨てられます。
正しい番号を取得するには、次のいずれかを行うことができます
BigDecimal#divide(BigDecimal)
メソッドを使用できます(scaleまたはRoundingMethodを提供しません)。あなたの場合、小数が終了しない可能性がないため、メソッドはArithmeticException
をスローしません(20/100 = 0.2、20/10000 = 0.002-小数は常に100で割ると終了します)。ただし、3などの別の数値で除算する場合は、小数点以下が終了しない可能性があるため、スケールを指定する必要があります(10/3 = 3.3333333333 ...と考えてください)。