如何在没有使用Java的科学符号的情况下打印双值?

时间:2022-10-30 23:41:24

I want to print a double value in Java without exponential form.

我想在Java中打印一个没有指数形式的双值。

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

It shows this E notation: 1.2345678E7.

它显示了E符号:1。2345678e7。

I want it to print it like this: 12345678

我想把它打印成这样:12345678

What is the best way to prevent this?

最好的预防方法是什么?

12 个解决方案

#1


82  

You could use printf() with %f:

您可以使用printf()和%f:

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

This will print dexp: 12345678.000000. If you don't want the fractional part, use

这将打印dexp: 12345678.000000。如果你不想要小数部分,使用

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

This uses the format specifier language explained in the documentation.

这使用了文档中解释的格式说明符语言。

The default toString() format used in your original code is spelled out here.

原始代码中使用的默认toString()格式在这里拼写出来。

#2


191  

Java prevent E notation in a double:

Five different ways to convert a double to a normal number:

五种不同的方法来转换一个双数到一个正常的数字:

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.println(new BigDecimal(myvalue).toPlainString());
        System.out.println();

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

This program prints:

这个程序打印:

2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000

Which are all the same value.

它们都是相同的值。

Protip: If you are confused as to why those random digits appear beyond a certain threshold in the double value, this video explains: computerphile why does 0.1+0.2 equal 0.30000000000001?

如果你不明白为什么这些随机数字出现在双值的某个阈值之外,这个视频解释了:计算机爱好者为什么0。1+0。2 = 0。3000000001 ?

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

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

#3


67  

In short:

简而言之:

If you want to get rid of trailing zeros and Locale problems, then you should use:

如果您想消除尾随零和语言环境问题,那么您应该使用:

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

Explanation:

解释:

Why other answers did not suit me:

为什么其他答案不适合我:

  • Double.toString() or System.out.println or FloatingDecimal.toJavaFormatString uses scientific notations if double is less than 10^-3 or greater than or equal to 10^7
  • Double.toString()或system . out。println或FloatingDecimal。toJavaFormatString使用科学符号如果双小于10 ^ 3或大于或等于10 ^ 7
  • By using %f, the default decimal precision is 6, otherwise you can hardcode it, but it results in extra zeros added if you have fewer decimals. Example:

    通过使用%f,默认的十进制精度是6,否则您可以硬编码它,但是如果小数更少,它会导致额外的0。例子:

    double myValue = 0.00000021d;
    String.format("%.12f", myvalue); // Output: 0.000000210000
    
  • By using setMaximumFractionDigits(0); or %.0f you remove any decimal precision, which is fine for integers/longs, but not for double:

    通过使用setMaximumFractionDigits(0);或%。如果你去掉了任何十进制的精度,这对于整数/longs来说都是可以的,但是对于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
    
  • By using DecimalFormat, you are local dependent. In French locale, the decimal separator is a comma, not a point:

    通过使用DecimalFormat,您是本地依赖的。在法语语言环境中,十进制分隔符是逗号,而不是点:

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

    Using the ENGLISH locale makes sure you get a point for decimal separator, wherever your program will run.

    使用英语语言环境可确保在程序运行的任何地方获得十进制分隔符。

Why using 340 then for setMaximumFractionDigits?

那么为什么对setmaximumfractionnumbers使用340呢?

Two reasons:

两个原因:

  • setMaximumFractionDigits accepts an integer, but its implementation has a maximum digits allowed of DecimalFormat.DOUBLE_FRACTION_DIGITS which equals 340
  • setmaximumfractiondigital接受一个整数,但是它的实现有一个允许使用DecimalFormat的最大数字。DOUBLE_FRACTION_DIGITS等于340
  • Double.MIN_VALUE = 4.9E-324 so with 340 digits you are sure not to round your double and lose precision.
  • 翻倍。MIN_VALUE = 4.9E-324,所以有340个数字,你肯定不会绕过你的双精度数。

#4


22  

You can try it with DecimalFormat. With this class you are very flexible in parsing your numbers.
You can exactly set the pattern you want to use.
In your case for example:

你可以用DecimalFormat试试。有了这个类,您可以非常灵活地解析数字。您可以准确地设置要使用的模式。以你为例:

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

#5


11  

I've got another solution involving BigDecimal's toPlainString(), but this time using the String-constructor, which is recommended in the javadoc:

我有另一个涉及BigDecimal的toPlainString()的解决方案,但是这次使用了string -构造函数,这在javadoc中是推荐的:

this constructor is compatible with the values returned by Float.toString and Double.toString. This is generally the preferred way to convert a float or double into a BigDecimal, as it doesn't suffer from the unpredictability of the BigDecimal(double) constructor.

此构造函数与Float返回的值兼容。toString和Double.toString。这通常是将浮点数或双精度数转换为BigDecimal的首选方法,因为它不会受到BigDecimal(double)构造函数不可预测性的影响。

It looks like this in its shortest form:

它的最短形式是这样的:

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

Pre Java 8, this results in "0.0" for any zero-valued Doubles, so you would need to add:

在Java 8之前,对于任何零值双精度浮点数,这将导致“0.0”,因此需要添加:

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

NaN and infinite values have to be checked extra.

NaN和无穷大值需要额外检查。

The final result of all these considerations:

所有这些考虑的最终结果是:

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

This can also be copied/pasted to work nicely with Float.

这也可以被复制/粘贴到与Float一起工作。

#6


8  

This will work as long as your number is a whole number:

只要你的号码是一个整数,这个就行了。

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

If the double variable has precision after the decimal point it will truncate it.

如果双变量在小数点后具有精度,它将截断它。

#7


4  

I needed to convert some double to currency values and found that most of the solutions were OK, but not for me.

我需要转换一些双倍的货币值,发现大多数的解决方案都可以,但对我来说不行。

The DecimalFormat was eventually the way for me, so here is what I've done:

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

As you can see, if the number is natural I get - say - 20000000 instead of 2E7 (etc.) - without any decimal point.

如你所见,如果数字是自然的,我得到- 20000000而不是2E7(等等)-没有小数点。

And if it's decimal, I get only two decimal digits.

如果它是十进制的,我只得到两位小数。

#8


3  

The following code detects if the provided number is presented in scientific notation. If so it is represented in normal presentation with a maximum of '25' digits.

下面的代码检测提供的数字是否以科学符号表示。如果是这样的话,它在正常的表示形式中以最大的“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);
}

#9


1  

I had this same problem in my production code when I was using it as a string input to a math.Eval() function which takes a string like "x + 20 / 50"

在我的生产代码中,当我把它作为一个字符串输入到math.Eval()函数时,我遇到了同样的问题,它使用了一个字符串,比如“x + 20 / 50”

I looked at hundreds of articles... In the end I went with this because of the speed. And because the Eval function was going to convert it back into its own number format eventually and math.Eval() didn't support the trailing E-07 that other methods returned, and anything over 5 dp was too much detail for my application anyway.

我看了几百篇文章……最后因为速度的原因,我选择了这个。因为Eval函数最终要将它转换成自己的数字格式,而math.Eval()不支持其他方法返回的末尾的E-07,而且对于我的应用程序来说,任何超过5dp的内容都太详细了。

This is now used in production code for an application that has 1,000+ users...

现在,对于一个拥有1000多个用户的应用程序来说,这是在产品代码中使用的……

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

s display as:  0.00021

#10


0  

I think everyone had the right idea, but all answers were not straightforward. I can see this being a very useful piece of code. Here is a snippet of what will work:

我认为每个人都有正确的想法,但所有的答案都不简单。我可以看到这是一段非常有用的代码。以下是一些有用的内容:

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

the ".8" is where you set the number of decimal places you would like to show.

”。8"是你想要显示的小数点数目。

I am using Eclipse and it worked no problem.

我正在使用Eclipse,它没有任何问题。

Hope this was helpful. I would appreciate any feedback!

希望这是有帮助的。我会很感激你的反馈!

#11


0  

For integer values represented by a double, you can use this code, which is much faster than the other solutions.

对于由double表示的整型值,可以使用此代码,它比其他解决方案快得多。

public static String doubleToString(final double d) {
    // check for integer, also see https://*.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);
}

#12


0  

Java/Kotlin compiler converts any value greater than 9999999 (greater than or equal to 10 million) to scientific notation ie. Epsilion notation.

Java/Kotlin编译器将任何大于999999999(大于或等于1000万)的值转换为科学符号ie。Epsilion符号。

Ex: 12345678 is converted to 1.2345678E7

例:12345678转换为1.2345678E7

Use this code to avoid automatic conversion to scientific notation:

使用此代码避免自动转换为科学符号:

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

#1


82  

You could use printf() with %f:

您可以使用printf()和%f:

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

This will print dexp: 12345678.000000. If you don't want the fractional part, use

这将打印dexp: 12345678.000000。如果你不想要小数部分,使用

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

This uses the format specifier language explained in the documentation.

这使用了文档中解释的格式说明符语言。

The default toString() format used in your original code is spelled out here.

原始代码中使用的默认toString()格式在这里拼写出来。

#2


191  

Java prevent E notation in a double:

Five different ways to convert a double to a normal number:

五种不同的方法来转换一个双数到一个正常的数字:

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.println(new BigDecimal(myvalue).toPlainString());
        System.out.println();

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

This program prints:

这个程序打印:

2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000

Which are all the same value.

它们都是相同的值。

Protip: If you are confused as to why those random digits appear beyond a certain threshold in the double value, this video explains: computerphile why does 0.1+0.2 equal 0.30000000000001?

如果你不明白为什么这些随机数字出现在双值的某个阈值之外,这个视频解释了:计算机爱好者为什么0。1+0。2 = 0。3000000001 ?

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

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

#3


67  

In short:

简而言之:

If you want to get rid of trailing zeros and Locale problems, then you should use:

如果您想消除尾随零和语言环境问题,那么您应该使用:

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

Explanation:

解释:

Why other answers did not suit me:

为什么其他答案不适合我:

  • Double.toString() or System.out.println or FloatingDecimal.toJavaFormatString uses scientific notations if double is less than 10^-3 or greater than or equal to 10^7
  • Double.toString()或system . out。println或FloatingDecimal。toJavaFormatString使用科学符号如果双小于10 ^ 3或大于或等于10 ^ 7
  • By using %f, the default decimal precision is 6, otherwise you can hardcode it, but it results in extra zeros added if you have fewer decimals. Example:

    通过使用%f,默认的十进制精度是6,否则您可以硬编码它,但是如果小数更少,它会导致额外的0。例子:

    double myValue = 0.00000021d;
    String.format("%.12f", myvalue); // Output: 0.000000210000
    
  • By using setMaximumFractionDigits(0); or %.0f you remove any decimal precision, which is fine for integers/longs, but not for double:

    通过使用setMaximumFractionDigits(0);或%。如果你去掉了任何十进制的精度,这对于整数/longs来说都是可以的,但是对于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
    
  • By using DecimalFormat, you are local dependent. In French locale, the decimal separator is a comma, not a point:

    通过使用DecimalFormat,您是本地依赖的。在法语语言环境中,十进制分隔符是逗号,而不是点:

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

    Using the ENGLISH locale makes sure you get a point for decimal separator, wherever your program will run.

    使用英语语言环境可确保在程序运行的任何地方获得十进制分隔符。

Why using 340 then for setMaximumFractionDigits?

那么为什么对setmaximumfractionnumbers使用340呢?

Two reasons:

两个原因:

  • setMaximumFractionDigits accepts an integer, but its implementation has a maximum digits allowed of DecimalFormat.DOUBLE_FRACTION_DIGITS which equals 340
  • setmaximumfractiondigital接受一个整数,但是它的实现有一个允许使用DecimalFormat的最大数字。DOUBLE_FRACTION_DIGITS等于340
  • Double.MIN_VALUE = 4.9E-324 so with 340 digits you are sure not to round your double and lose precision.
  • 翻倍。MIN_VALUE = 4.9E-324,所以有340个数字,你肯定不会绕过你的双精度数。

#4


22  

You can try it with DecimalFormat. With this class you are very flexible in parsing your numbers.
You can exactly set the pattern you want to use.
In your case for example:

你可以用DecimalFormat试试。有了这个类,您可以非常灵活地解析数字。您可以准确地设置要使用的模式。以你为例:

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

#5


11  

I've got another solution involving BigDecimal's toPlainString(), but this time using the String-constructor, which is recommended in the javadoc:

我有另一个涉及BigDecimal的toPlainString()的解决方案,但是这次使用了string -构造函数,这在javadoc中是推荐的:

this constructor is compatible with the values returned by Float.toString and Double.toString. This is generally the preferred way to convert a float or double into a BigDecimal, as it doesn't suffer from the unpredictability of the BigDecimal(double) constructor.

此构造函数与Float返回的值兼容。toString和Double.toString。这通常是将浮点数或双精度数转换为BigDecimal的首选方法,因为它不会受到BigDecimal(double)构造函数不可预测性的影响。

It looks like this in its shortest form:

它的最短形式是这样的:

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

Pre Java 8, this results in "0.0" for any zero-valued Doubles, so you would need to add:

在Java 8之前,对于任何零值双精度浮点数,这将导致“0.0”,因此需要添加:

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

NaN and infinite values have to be checked extra.

NaN和无穷大值需要额外检查。

The final result of all these considerations:

所有这些考虑的最终结果是:

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

This can also be copied/pasted to work nicely with Float.

这也可以被复制/粘贴到与Float一起工作。

#6


8  

This will work as long as your number is a whole number:

只要你的号码是一个整数,这个就行了。

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

If the double variable has precision after the decimal point it will truncate it.

如果双变量在小数点后具有精度,它将截断它。

#7


4  

I needed to convert some double to currency values and found that most of the solutions were OK, but not for me.

我需要转换一些双倍的货币值,发现大多数的解决方案都可以,但对我来说不行。

The DecimalFormat was eventually the way for me, so here is what I've done:

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

As you can see, if the number is natural I get - say - 20000000 instead of 2E7 (etc.) - without any decimal point.

如你所见,如果数字是自然的,我得到- 20000000而不是2E7(等等)-没有小数点。

And if it's decimal, I get only two decimal digits.

如果它是十进制的,我只得到两位小数。

#8


3  

The following code detects if the provided number is presented in scientific notation. If so it is represented in normal presentation with a maximum of '25' digits.

下面的代码检测提供的数字是否以科学符号表示。如果是这样的话,它在正常的表示形式中以最大的“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);
}

#9


1  

I had this same problem in my production code when I was using it as a string input to a math.Eval() function which takes a string like "x + 20 / 50"

在我的生产代码中,当我把它作为一个字符串输入到math.Eval()函数时,我遇到了同样的问题,它使用了一个字符串,比如“x + 20 / 50”

I looked at hundreds of articles... In the end I went with this because of the speed. And because the Eval function was going to convert it back into its own number format eventually and math.Eval() didn't support the trailing E-07 that other methods returned, and anything over 5 dp was too much detail for my application anyway.

我看了几百篇文章……最后因为速度的原因,我选择了这个。因为Eval函数最终要将它转换成自己的数字格式,而math.Eval()不支持其他方法返回的末尾的E-07,而且对于我的应用程序来说,任何超过5dp的内容都太详细了。

This is now used in production code for an application that has 1,000+ users...

现在,对于一个拥有1000多个用户的应用程序来说,这是在产品代码中使用的……

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

s display as:  0.00021

#10


0  

I think everyone had the right idea, but all answers were not straightforward. I can see this being a very useful piece of code. Here is a snippet of what will work:

我认为每个人都有正确的想法,但所有的答案都不简单。我可以看到这是一段非常有用的代码。以下是一些有用的内容:

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

the ".8" is where you set the number of decimal places you would like to show.

”。8"是你想要显示的小数点数目。

I am using Eclipse and it worked no problem.

我正在使用Eclipse,它没有任何问题。

Hope this was helpful. I would appreciate any feedback!

希望这是有帮助的。我会很感激你的反馈!

#11


0  

For integer values represented by a double, you can use this code, which is much faster than the other solutions.

对于由double表示的整型值,可以使用此代码,它比其他解决方案快得多。

public static String doubleToString(final double d) {
    // check for integer, also see https://*.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);
}

#12


0  

Java/Kotlin compiler converts any value greater than 9999999 (greater than or equal to 10 million) to scientific notation ie. Epsilion notation.

Java/Kotlin编译器将任何大于999999999(大于或等于1000万)的值转换为科学符号ie。Epsilion符号。

Ex: 12345678 is converted to 1.2345678E7

例:12345678转换为1.2345678E7

Use this code to avoid automatic conversion to scientific notation:

使用此代码避免自动转换为科学符号:

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