40

私はdouble値を持っています= 1.0688793351.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;

4

10 に答える 10

83

文字列のコンマに注意してください:「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;

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

于 2011-01-25T17:34:40.900 に答える
21

@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

編集:Sergeyが指摘しているように、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
于 2011-01-25T18:30:08.140 に答える
8

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

double rounded = (double) Math.round(value * 100.0) / 100.0;
于 2011-01-25T17:35:35.907 に答える
4

あなたがやろうとしていることに根本的に何か問題があります。2進浮動小数点値には小数点以下の桁数はありません。ほとんどの「丸める」小数値は単純に2進数として表すことができないため、1を指定された小数点以下の桁数に意味のある形で丸めることはできません。だからこそ、お金を使っfloatたり、表現したりしてはいけません。double

したがって、結果に小数点以下の桁数が必要な場合、その結果はString(ですでに取得しているDecimalFormat)またはBigDecimalsetScale()必要なことを正確に実行するメソッドを持っている)のいずれかである必要があります。そうしないと、結果が希望どおりになることはありません。

詳細については、浮動小数点ガイドをお読みください。

于 2011-01-25T17:37:37.857 に答える
3

これを試してください: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;
        }
    }
}
于 2014-02-20T05:00:55.527 に答える
1

新しいDecimalFormatを定義し、それを新しいdouble変数のDouble結果として使用してみることができます。

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

double decimalnumber = 100.2397;
DecimalFormat dnf = new DecimalFormat( "#,###,###,##0.00" );
double roundednumber = new Double(dnf.format(decimalnumber)).doubleValue();
于 2011-01-25T17:30:25.027 に答える
1

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

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

于 2011-01-25T17:35:06.943 に答える
1
double TotalPrice=90.98989898898;

  DecimalFormat format_2Places = new DecimalFormat("0.00");

    TotalPrice = Double.valueOf(format_2Places.format(TotalPrice));
于 2013-09-11T13:12:33.997 に答える
0

ここのようなフォーマットを使用できます、

  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;   
    }
}
于 2013-11-18T12:08:40.237 に答える
0

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;
}
于 2019-04-09T04:23:28.893 に答える