Java를 사용하여 과학적 표기법없이 이중 값을 인쇄하려면 어떻게합니까?


222

지수 형태없이 Java에서 이중 값을 인쇄하고 싶습니다.

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어느 것이 잘못된 값인지 보여주었습니다. 실제로 그 후에 웹 페이지에 다음과 같이 표시하고 싶습니다. 1.2345678E7어쨌든 두 배나 12345678다른 방법으로 저장할 수 있습니까?
비열

1
@despicable : 답이 구식이고 불완전한 버전을보고있을 수 있습니다. 페이지를 다시로드하십시오. 에 대한 단락이 있어야합니다 %.0f.
NPE

@despicable dexp를 int로 저장하여 두 가지 방식으로 쉽게 사용할 수 있습니다.
Justin

10
그것은 숫자에서
벗어납니다

6
%.0f숫자를 반올림합니다. 후행 0을 버리는 방법이 있습니까?
NurShomik

239

Java는 이중으로 E 표기를 방지합니다.

double을 일반 숫자로 변환하는 다섯 가지 방법 :

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 : 당신은 그 임의의 숫자가 두 배 값에 특정 임계 값을 초과 표시 이유에 대해 혼동하는 경우,이 비디오는 설명 : computerphile 이유는 무엇입니까 0.1+ 0.2같음 0.30000000000001?

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


답변과 팁에 감사드립니다. 그 비디오는 저의 혼란을 해결했습니다.
AnujDeo

97

한마디로 :

후행 0과 로케일 문제를 제거하려면 다음을 사용해야합니다.

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()또는 System.out.println또는 FloatingDecimal.toJavaFormatString이중 10 개 미만인 경우 ^ -3 과학적 표기법을 사용하거나보다 큰 10 ^ 7 동등
  • 을 사용 %f하면 기본 10 진수 정밀도는 6이며, 그렇지 않으면 하드 코딩 할 수 있지만 소수가 적 으면 추가 0이 추가됩니다. 예:

    double myValue = 0.00000021d;
    String.format("%.12f", myvalue); // Output: 0.000000210000
  • 사용하여 setMaximumFractionDigits(0);%.0f10 진수 정밀도 하거나 제거하면 정수 / 길이에는 적합하지만 double에는 적합하지 않습니다.

    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합니까?

두 가지 이유 :

  • 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

4
new BigDecimal(0.00000021d).toPlainString()0.0000002100000000000000010850153241148685623329583904705941677093505859375예상치 못한 결과물 ...
JBE

스칼라에서 답을 사용하는 방법에 대한 아이디어가 있습니까? 아마도 적절한 수입 문제 일지 모르지만 여기에 처음입니다.
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에서 반환 된 값과 호환됩니다. 이는 일반적으로 float 또는 double을 BigDecimal로 변환하는 데 선호되는 방법입니다. BigDecimal (double) 생성자의 예측 불가능 성을 겪지 않기 때문입니다.

가장 짧은 형태로 다음과 같이 보입니다.

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

Pre Java 8에서는 값이 0 인 Double에 대해 "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
이중 값을 문자열로 변환하는 수많은 구성표를 읽었으며 짧고 간단하며 구성 가능한 것이 가장 좋습니다.
Paul

훌륭한 솔루션은 실제로 이중 값을 문자열로 변환하고 과학적 표기법을 피하는 데 도움이되었습니다. 감사!
pleft

d.doubleValue() == 0대신에 d == 0?
Alexei Fando

자동 unboxing을 피하기 때문에 그 상황에서 더 좋아하지만 뷰는 이것과 다를 수 있습니다. Java 8을 사용하는 경우 (9는 아마도 같을 것입니다) 두 줄을 모두 생략 할 수 있습니다.
Manuel

Java 9로 방금 시도한 결과 두 줄은 9에 남겨 둘 수 있습니다.
Manuel

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 (예 : 2020) 대신 20000000을 얻습니다.

그리고 십진수이면 두 자리 숫자 만 얻습니다.


4

Java / Kotlin 컴파일러는 9999999보다 큰 (1000 만 이상) 모든 값을 과학적 표기법으로 변환합니다. 엡 실리온 표기법 .

예 : 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을 지원하지 않았으므로 5dp 이상은 내 응용 프로그램에 대해 너무 자세했습니다. .

이제 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

이것은 탄젠트 일 수 있습니다 ....하지만 숫자 값을 정수 (너무 너무 큰 정수)로 serializer (JSON 등)에 넣으려면 "BigInterger"를 원할 것입니다

예 : value는 문자열입니다-7515904334

Json 메시지에서 숫자로 표시해야합니다. { "contact_phone": "800220-3333", "servicer_id": 7515904334, "servicer_name": "SOME CORPORATION"}

인쇄 할 수 없거나 다음과 같이 표시됩니다 : { "contact_phone": "800220-3333", "servicer_id": "7515904334", "servicer_name": "일부 CORPORATION"}

이와 같이 노드에 값을 추가하면 원하는 결과가 생성됩니다. BigInteger.valueOf (Long.parseLong (value, 10))

나는 이것이 실제로 주제가 될지 확신하지 못하지만이 질문이 내 솔루션을 검색했을 때 가장 큰 인기를 얻었으므로 다른 사람들의 이익을 위해 여기에 공유하고 잘못 검색하는 거짓말을 할 것이라고 생각했습니다. :디


-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.