質問

二重値=があります 1.068879335 1.07のような小数値が2つだけで締めくくりたいと思います。

私はこのように試しました

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)

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

finaly finalValue =が必要です 1.07;

役に立ちましたか?

解決

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

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

他のヒント

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

編集: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

問題は、ロケール固有の小数点を生成するローカライズフォーマッタを使用することです。これは「」、「」です。ただし、double.parsedouble()は、局在化されていない二重リテラルを期待しています。ロケール固有の解析方法を使用するか、フォーマッターのロケールを使用するものに変更することで、問題を解決できます。小数点として。またはさらに良いことに、次のようなものを使用して、不必要なフォーマットを避けてください。

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

あなたがやろうとしていることには根本的に間違っていることがあります。バイナリフローティングポイント値はありません 持ってる 小数位。ほとんどの「丸い」小数値をバイナリ画分として表すことができないため、特定の小数の場所から特定の小数の場所を有意に丸めることはできません。それが決して使用すべきではない理由です float また double お金を表すために。

したがって、結果に小数点以下の場所が必要な場合、その結果は String (あなたはすでに持っています DecimalFormat)、またはa BigDecimal (aがあります setScale() 必要なことを正確に行う方法)。それ以外の場合、結果はあなたが望むものになることはできません。

読んだ フローティングポイントガイド 詳細については。

これを試してください: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;
        }
    }
}

新しいDecimalFormatを定義し、それを新しいダブル変数への二重結果として使用してみてください。

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

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

IEEEフローティングポイント番号を使用して正確に表現できない2つの小数点を持つ数字があるため、これは要求された方法で不可能です(たとえば、1/10 = 0.1は、 Double また Float)。フォーマットは、結果をユーザーに提示する前に、常に最後のステップとして発生する必要があります。

金銭的価値に対処したいので、あなたは尋ねていると思います。これをフローティングポイント番号で確実に行う方法はありません。固定点算術に切り替えることを検討します。これは、おそらく「ドル」ではなく「セント」ですべての計算を行うことを意味します。

double TotalPrice=90.98989898898;

  DecimalFormat format_2Places = new DecimalFormat("0.00");

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

次の形式を使用できます ここ,

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

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;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top