Javaを使用して科学表記なしでdouble値を出力するにはどうすればよいですか?


222

指数形式なしでJavaでdouble値を出力したい。

double dexp = 12345678;
System.out.println("dexp: "+dexp);

次のE表記を示しています1.2345678E7

私はそれを次のように印刷したいです: 12345678

これを防ぐ最善の方法は何ですか?

回答:


116

あなたはprintf()と一緒に使うことができます%f

double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);

これは印刷されますdexp: 12345678.000000。小数部が不要な場合は、

System.out.printf("dexp: %.0f\n", dexp);

これは、ドキュメントで説明されているフォーマット指定子言語を使用します

toString()元のコードで使用されているデフォルトの形式がスペルアウトされていますここに記載さます


1
しかし、それはdexp: 12345681.000000どちらが間違った値であるかを示しました。実際には、それを私のWebページに表示したいのですが、このように表示さ1.2345678E7れます 12345678
2013

1
@卑劣な:あなたは答えの古い、不完全なバージョンを見ていた可能性があります。ページをリロードしてみてください。に関する段落があり%.0fます。
NPE 2013

@despicableあなたはdexpをintとして保存できるので、両方の方法で簡単に使用できます
Justin

10
ITは数字を丸める
2015年

6
%.0f数値を四捨五入します。末尾のゼロを破棄する方法はありますか?
NurShomik 2017年

239

JavaはE表記を二重に防止します。

doubleを通常の数値に変換する5つの方法:

import java.math.BigDecimal;
import java.text.DecimalFormat;

public class Runner {
    public static void main(String[] args) {
        double myvalue = 0.00000021d;

        //Option 1 Print bare double.
        System.out.println(myvalue);

        //Option2, use decimalFormat.
        DecimalFormat df = new DecimalFormat("#");
        df.setMaximumFractionDigits(8);
        System.out.println(df.format(myvalue));

        //Option 3, use printf.
        System.out.printf("%.9f", myvalue);
        System.out.println();

        //Option 4, convert toBigDecimal and ask for toPlainString().
        System.out.print(new BigDecimal(myvalue).toPlainString());
        System.out.println();

        //Option 5, String.format 
        System.out.println(String.format("%.12f", myvalue));
    }
}

このプログラムは以下を出力します:

2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000

どれも同じ値です。

Protipは:あなたがそれらのランダムな数字がdouble値に一定のしきい値を超えて現れる理由として混乱している場合は、このビデオは説明する:computerphileなぜ0.1+ 0.2等しいですか0.30000000000001

http://youtube.com/watch?v=PZRI1IfStY0


回答、特にヒントをありがとうございます。そのビデオは私の混乱を解決しました。
AnujDeo

97

要するに:

末尾のゼロとロケールの問題を取り除きたい場合は、以下を使用する必要があります。

double myValue = 0.00000021d;

DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS

System.out.println(df.format(myValue)); // Output: 0.00000021

説明:

他の答えが私に合わなかった理由:

  • Double.toString()or System.out.printlnまたはFloatingDecimal.toJavaFormatStringdoubleが10 ^ -3未満または10 ^ 7以上の場合は科学表記法を使用
  • を使用する%fと、デフォルトの小数精度は6になります。それ以外の場合はハードコードできますが、小数が少ないとゼロが追加されます。例:

    double myValue = 0.00000021d;
    String.format("%.12f", myvalue); // Output: 0.000000210000
  • 使用することによりsetMaximumFractionDigits(0);、または%.0fあなたは、二重のために、整数/ long型の罰金である任意の10進精度を、削除ではなく:

    double myValue = 0.00000021d;
    System.out.println(String.format("%.0f", myvalue)); // Output: 0
    DecimalFormat df = new DecimalFormat("0");
    System.out.println(df.format(myValue)); // Output: 0
  • DecimalFormatを使用すると、ローカルに依存します。フランス語ロケールでは、小数点記号はポイントではなくコンマです。

    double myValue = 0.00000021d;
    DecimalFormat df = new DecimalFormat("0");
    df.setMaximumFractionDigits(340);
    System.out.println(df.format(myvalue)); // Output: 0,00000021

    ENGLISHロケールを使用すると、プログラムが実行される場所に関係なく、小数点のポイントを確実に取得できます。

なぜ340を使用するのか setMaximumFractionDigitsですか?

2つの理由:

  • setMaximumFractionDigits 整数を受け入れますが、その実装には最大許容桁数があります DecimalFormat.DOUBLE_FRACTION_DIGITSが340です。
  • Double.MIN_VALUE = 4.9E-324 したがって、340桁を使用すると、倍精度を四捨五入して精度を失うことはありません。

あなたの意見は何ですかdocs.oracle.com/javase/7/docs/api/java/math/…new BigDecimal(myvalue).toPlainString()の説明から、異なるタイプの数値が与えられたときの動作はすぐにはわかりませんが、科学的表記を排除します。
Derek Mahar、2015

4
new BigDecimal(0.00000021d).toPlainString()0.0000002100000000000000010850153241148685623329583904705941677093505859375あなたが期待するものではない出力...
JBE 2015

scalaで回答を使用する方法はありますか?おそらく適切なインポートの問題ですが、私はここで新しいです。
jangorecki

BigDecimal.valueOf(0.00000021d).toPlainString()動作します(そのためBigDecimalのStringコンストラクターを使用します)
marco

27

で試すことができDecimalFormatます。このクラスを使用すると、数値の解析に非常に柔軟性があります。
使いたいパターンを正確に設定できます。
あなたの例では:

double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678

16

BigDecimalのtoPlainString()を含む別の解決策がありますが、今回はjavadocで推奨されているStringコンストラクターを使用します。

このコンストラクタは、Float.toStringおよびDouble.toStringによって返される値と互換性があります。これは、BigDecimal(double)コンストラクターの予測不能性の影響を受けないため、floatまたはdoubleをBigDecimalに変換するための一般的な推奨方法です。

最短形式では次のようになります。

return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();

Java 8より前の場合、これはゼロ値の倍精度浮動小数点数に対して「0.0」になるため、以下を追加する必要があります。

if (myDouble.doubleValue() == 0)
    return "0";

NaNと無限値は追加でチェックする必要があります。

これらすべての考慮事項の最終結果:

public static String doubleToString(Double d) {
    if (d == null)
        return null;
    if (d.isNaN() || d.isInfinite())
        return d.toString();

    // Pre Java 8, a value of 0 would yield "0.0" below
    if (d.doubleValue() == 0)
        return "0";
    return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}

これは、Floatとうまく連携するようにコピー/貼り付けすることもできます。


2
私はdouble値を文字列に変換するための無数のスキームを読んだことがあり、これが最良です。短く、簡単で、構成可能です。
ポール

素晴らしい解決策で、double値をStringに変換し、科学表記法を回避するのに本当に役立ちました。ありがとう!
pleft

なぜd.doubleValue() == 0代わりにd == 0
Alexei Fando 2017年

自動アンボクシングは回避されますが、そのような状況では私はより良いと思いますが、もちろんこれについてはビューが異なる場合があります。Java 8を使用している場合(9はおそらく同じでしょう)、これらの2行を完全に省略することができます。
マヌエル、

Java 9で試したところ、これらの2行は9でも省略できます。
マヌエル、

8

これは、数値が整数である限り機能します。

double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);

double変数に小数点以下の精度がある場合、切り捨てられます。


4

いくつかのダブルを通貨の値に変換する必要があり、ほとんどの解決策は問題ないが、私には適さないことがわかりました。

DecimalFormat最終的にはそれが私にとっての道だったので、これが私がやったことです:

   public String foo(double value) //Got here 6.743240136E7 or something..
    {
        DecimalFormat formatter;

        if(value - (int)value > 0.0)
            formatter = new DecimalFormat("0.00"); // Here you can also deal with rounding if you wish..
        else
            formatter = new DecimalFormat("0");

        return formatter.format(value);
    }

ご覧のとおり、数値が自然である場合、たとえば、2E7ではなく20000000などが得られます。小数点はありません。

10進数の場合、10進数は2桁しかありません。


4

Java / Kotlinコンパイラは、9999999を超える値(1000万以上)を科学表記に変換します。Epsilion表記

例:12345678は1.2345678E7に変換されます

このコードを使用して、科学表記法への自動変換を回避します。

fun setTotalSalesValue(String total) {
        var valueWithoutEpsilon = total.toBigDecimal()
        /* Set the converted value to your android text view using setText() function */
        salesTextView.setText( valueWithoutEpsilon.toPlainString() )
    }

3

次のコードは、指定された数値が科学表記法で示されているかどうかを検出します。その場合は、通常の表示で最大 '25'桁で表されます。

 static String convertFromScientificNotation(double number) {
    // Check if in scientific notation
    if (String.valueOf(number).toLowerCase().contains("e")) {
        System.out.println("The scientific notation number'"
                + number
                + "' detected, it will be converted to normal representation with 25 maximum fraction digits.");
        NumberFormat formatter = new DecimalFormat();
        formatter.setMaximumFractionDigits(25);
        return formatter.format(number);
    } else
        return String.valueOf(number);
}

1

誰もが正しい考えを持っていると思いますが、すべての答えは簡単ではありませんでした。これは非常に便利なコードです。これが機能するスニペットです:

System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));

".8"あなたが表示したいと思い小数点以下の桁数を設定する場所です。

私はEclipseを使用していますが、問題なく動作しました。

これがお役に立てば幸いです。フィードバックをいただければ幸いです。


1

"x + 20/50"のような文字列を受け取るmath.Eval()関数への文字列入力として使用していたとき、本番コードで同じ問題が発生しました

私は何百もの記事を見ました...結局私はスピードのためにこれに行きました。そして、Eval関数はそれを独自の数値形式に最終的に変換し、math.Eval()は他のメソッドが返す末尾のE-07をサポートしなかったため、5 dpを超えるものは、とにかく私のアプリケーションには詳細すぎました。

これは現在、1,000人以上のユーザーがいるアプリケーションのプロダクションコードで使用されています...

double value = 0.0002111d;
String s = Double.toString(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp

s display as:  0.00021

1

これは正接である可能性があります...しかし、数値を整数(整数には大きすぎる)としてシリアライザ(JSONなど)に挿入する必要がある場合は、おそらく「BigInterger」が必要です。

例:値は文字列です-7515904334

Jsonメッセージで数値として表す必要があります:{"contact_phone": "800220-3333"、 "servicer_id":7515904334、 "servicer_name": "SOME CORPORATION"}

印刷できないか、次の形式で取得されます:{"contact_phone": "800220-3333"、 "servicer_id": "7515904334"、 "servicer_name": "SOME CORPORATION"}

次のようにノードに値を追加すると、望ましい結果が得られます:BigInteger.valueOf(Long.parseLong(value、10))

これが本当に話題になっているのかはわかりませんが、この質問は自分の解決策を検索したときの一番のヒットだったので、検索がうまくいかない他の人のために、ここで共有したいと思いました。:D


-1

で表される整数値の場合double、このコードを使用できます。これは、他のソリューションよりもはるかに高速です。

public static String doubleToString(final double d) {
    // check for integer, also see https://stackoverflow.com/a/9898613/868941 and
    // https://github.com/google/guava/blob/master/guava/src/com/google/common/math/DoubleMath.java
    if (isMathematicalInteger(d)) {
        return Long.toString((long)d);
    } else {
        // or use any of the solutions provided by others
        return Double.toString(d);
    }
}

// Java 8+
public static boolean isMathematicalInteger(final double d) {
    return StrictMath.rint(d) == d && Double.isFinite(d);
}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.