web-dev-qa-db-ja.com

切り上げる倍精度値Java

Double値= 1.068879335があります。1.07のような2つの10進値のみで切り上げます。

こうやってみた

DecimalFormat df=new DecimalFormat("0.00");
String formate = df.format(value);
double finalValue = Double.parseDouble(formate) ;

これは私にこの次の例外を与えています

Java.lang.NumberFormatException: For input string: "1,07"
     at Sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.Java:1224)
     at Java.lang.Double.parseDouble(Double.Java:510)

誰かが私のコードの何が悪いのか教えてもらえますか。

最後に、finalValue = 1.07;が必要です

35
jimmy

文字列内のカンマ「1,07」に注意してください。 DecimalFormatはロケール固有の区切り文字列を使用しますが、Double.parseDouble()は使用しません。小数点記号が "、"である国に住んでいると、数値を元に戻すことはできません。

ただし、同じDecimalFormatを使用して解析することができます。

DecimalFormat df=new DecimalFormat("0.00");
String formate = df.format(value); 
double finalValue = (Double)df.parse(formate) ;

ただし、代わりにこれを実際に行う必要があります。

double finalValue = Math.round( value * 100.0 ) / 100.0;

注:指摘したように、浮動小数点は、精度を正確に制御する必要がない場合にのみ使用してください。 (財務計算は、notを使用する場合の主な例です。)

78
biziclop

Live @Sergeyのソリューションですが、整数除算を使用します。

double value = 23.8764367843;
double rounded = (double) Math.round(value * 100) / 100;
System.out.println(value +" rounded is "+ rounded);

プリント

23.8764367843 rounded is 23.88

編集:セルゲイが指摘するように、double * intとdouble * doubleの乗算とdouble/intとdouble/doubleの除算に違いはないはずです。結果が異なる例を見つけることができません。ただし、x86/x64およびその他のシステムでは、JVMが使用していると思われる混合double、int値用の特定のマシンコード命令があります。

for (int j = 0; j < 11; j++) {
    long start = System.nanoTime();
    for (double i = 1; i < 1e6; i *= 1.0000001) {
        double rounded = (double) Math.round(i * 100) / 100;
    }
    long time = System.nanoTime() - start;
    System.out.printf("double,int operations %,d%n", time);
}
for (int j = 0; j < 11; j++) {
    long start = System.nanoTime();
    for (double i = 1; i < 1e6; i *= 1.0000001) {
        double rounded = (double) Math.round(i * 100.0) / 100.0;
    }
    long time = System.nanoTime() - start;
    System.out.printf("double,double operations %,d%n", time);
}

プリント

double,int operations 613,552,212
double,int operations 661,823,569
double,int operations 659,398,960
double,int operations 659,343,506
double,int operations 653,851,816
double,int operations 645,317,212
double,int operations 647,765,219
double,int operations 655,101,137
double,int operations 657,407,715
double,int operations 654,858,858
double,int operations 648,702,279
double,double operations 1,178,561,102
double,double operations 1,187,694,386
double,double operations 1,184,338,024
double,double operations 1,178,556,353
double,double operations 1,176,622,937
double,double operations 1,169,324,313
double,double operations 1,173,162,162
double,double operations 1,169,027,348
double,double operations 1,175,080,353
double,double operations 1,182,830,988
double,double operations 1,185,028,544
20
Peter Lawrey

問題は、ロケール固有の小数点を生成するローカライズフォーマッターを使用することです。これは、「、」です。ただし、Double.parseDouble()は、ローカライズされていないdoubleリテラルを想定しています。ロケール固有の解析方法を使用するか、フォーマッターのロケールを「。」を使用するものに変更することにより、問題を解決できます。小数点として。または、次のようなものを使用して、不要な書式設定を避けてください。

double rounded = (double) Math.round(value * 100.0) / 100.0;
8
Sergei Tachenov

あなたがやろうとしていることには根本的に間違ったことがあります。バイナリ浮動小数点値は、小数点以下の桁数を持ちません。ほとんどの「丸められた」10進値は、単に2進小数として表すことができないため、1を指定された小数点以下の桁数に有意に丸めることはできません。お金を表すためにfloatまたはdoubleを決して使用してはならない理由です。

結果に小数点以下の桁数が必要な場合、その結果はStringDecimalFormatで既に取得済み)、またはBigDecimalsetScale()必要なことを正確に行うメソッド)。それ以外の場合、結果は期待どおりにはなりません。

詳細については、「 浮動小数点ガイド 」を参照してください。

4

これを試してください:org.Apache.commons.math3.util.Precision.round(double x、int scale)

参照: http://commons.Apache.org/proper/commons-math/apidocs/org/Apache/commons/math3/util/Precision.html

Apache Commons Mathematics Libraryホームページ: http://commons.Apache.org/proper/commons-math/index.html

このメソッドの内部実装は次のとおりです。

public static double round(double x, int scale) {
    return round(x, scale, BigDecimal.ROUND_HALF_UP);
}

public static double round(double x, int scale, int roundingMethod) {
    try {
        return (new BigDecimal
               (Double.toString(x))
               .setScale(scale, roundingMethod))
               .doubleValue();
    } catch (NumberFormatException ex) {
        if (Double.isInfinite(x)) {
            return x;
        } else {
            return Double.NaN;
        }
    }
}
2
Li Ying

新しいDecimalFormatを定義し、それを新しいdouble変数のDouble結果として使用してみてください。

私がちょうど言ったことをあなたに理解させるために与えられた例。

double decimalnumber = 100.2397;
DecimalFormat dnf = new DecimalFormat( "#,###,###,##0.00" );
double roundednumber = new Double(dnf.format(decimalnumber)).doubleValue();
1
Markku
double TotalPrice=90.98989898898;

  DecimalFormat format_2Places = new DecimalFormat("0.00");

    TotalPrice = Double.valueOf(format_2Places.format(TotalPrice));
1
DeltaCap019

IEEE浮動小数点数を使用して正確に表現できない小数点以下2桁の数値があるため、これは要求された方法では不可能です(たとえば、1/10 = 0.1はDoubleまたはFloatとして表現できません)。フォーマットは、ユーザーに結果を表示する前の最後のステップとして常に行われるべきです。

あなたは金銭的価値に対処したいのであなたが尋ねていると思います。浮動小数点数でこれを確実に行う方法はありません。固定小数点演算への切り替えを検討してください。これはおそらく、すべての計算を「ドル」ではなく「セント」で行うことを意味します。

1
Waldheinz

DecimalFormatを使用したくない場合(効率のためなど)、一般的なソリューションが必要な場合は、スケーリングされた丸めを使用するこのメソッドを試すこともできます。

public static double roundToDigits(double value, int digitCount) {
    if (digitCount < 0)
        throw new IllegalArgumentException("Digit count must be positive for rounding!");

    double factor = Math.pow(10, digitCount);
    return (double)(Math.round(value * factor)) / factor;
}
0
Keplerian

here などの形式を使用できます。

  public static double getDoubleValue(String value,int digit){
    if(value==null){
        value="0";
     }
    double i=0;
     try {
         DecimalFormat digitformat = new DecimalFormat("#.##");
         digitformat.setMaximumFractionDigits(digit);
        return Double.valueOf(digitformat.format(Double.parseDouble(value)));

    } catch (NumberFormatException numberFormatExp) {
        return i;   
    }
}
0
Knowledge Serve