現在、私はこの方法を持っています:
static boolean checkDecimalPlaces(double d, int decimalPlaces){
if (d==0) return true;
double multiplier = Math.pow(10, decimalPlaces);
double check = d * multiplier;
check = Math.round(check);
check = check/multiplier;
return (d==check);
}
checkDecmialPlaces(649632196443.4279, 4)
しかし、おそらく私が基数2の数値に基づいて基数10の計算を行うため、この方法は失敗します。
では、このチェックを正しく行うにはどうすればよいでしょうか。
double値の文字列表現を取得し、それを正規表現で確認することを考えましたが、それは奇妙に感じました。
編集: すべての答えをありがとう。私が実際にダブルを取得する場合があり、それらの場合のために私は以下を実装しました:
private static boolean checkDecimalPlaces(double d, int decimalPlaces) {
if (d == 0) return true;
final double epsilon = Math.pow(10.0, ((decimalPlaces + 1) * -1));
double multiplier = Math.pow(10, decimalPlaces);
double check = d * multiplier;
long checkLong = (long) Math.abs(check);
check = checkLong / multiplier;
double e = Math.abs(d - check);
return e < epsilon;
}
round
を切り捨てに変更しました。で行われた計算round
により、不正確さが大きくなりすぎるようです。少なくとも失敗したテストケースでは。「実際の」文字列入力に到達できるかどうかを確認するために
使用する必要があると指摘された方もいらっしゃるので、次のようにしました。BigDecimal
BigDecimal decimal = new BigDecimal(value);
BigDecimal checkDecimal = decimal.movePointRight(decimalPlaces);
return checkDecimal.scale() == 0;
私が得る価値は、double
Excelファイルを読み取るApachePOIAPIから得られます。いくつかのテストを行ったところ、APIはdouble
数値セルの値を返しますが、すぐに次のようにフォーマットすると正確な表現を取得できることがdouble
わかりましたDecimalFormat
。
DecimalFormat decimalFormat = new DecimalFormat();
decimalFormat.setMaximumIntegerDigits(Integer.MAX_VALUE);
// don't use grouping for numeric-type cells
decimalFormat.setGroupingUsed(false);
decimalFormat.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
value = decimalFormat.format(numericValue);
これは、バイナリ形式で正確に表すことができない値に対しても機能します。