我如何打印一个双值没有科学符号使用Java?

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

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

它显示了E符号:1.2345678E7

我希望它像这样打印:12345678

预防这种情况的最好方法是什么?

425226 次浏览

你可以使用printf()%f:

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

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

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

%.0f中的0表示小数部分有0个位置,即没有小数部分。如果你想打印所需小数位数的小数部分,那么只需提供像%.8f这样的数字,而不是0。默认情况下,小数部分打印到小数点后6位。

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

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

你可以用DecimalFormat来尝试。使用这个类,你可以非常灵活地解析你的数字 你可以精确地设置你想要使用的模式 以你的例子为例:

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

只要你的号码是整数,这个方法就有效:

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

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

Java防止E表示法出现双元:

五种将双精度数转换为正数的方法:

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值的某个阈值之外感到困惑,这个视频解释:为什么0.1+0.2等于0.30000000000001?

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

简而言之:

如果你想摆脱尾随0和Locale问题,那么你应该使用:

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小于10^ 3或大于或等于10^7,则Double.toString()System.out.printlnFloatingDecimal.toJavaFormatString使用科学符号
  • 通过使用%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:

    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:

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

    使用英语区域设置可以确保在程序运行的任何地方获得一个小数点分隔符点

为什么对setMaximumFractionDigits使用340呢?

两个原因:

  • setMaximumFractionDigits接受一个整数,但它的实现允许的最大数字为DecimalFormat.DOUBLE_FRACTION_DIGITS,等于340
  • Double.MIN_VALUE = 4.9E-324所以340位你肯定不会四舍五入的双精度和损失精度。

下面的代码检测所提供的数字是否以科学计数法表示。如果是这样,则在正常表示中使用最多“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);
}

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

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

这现在被用于有1000多个用户的应用程序的生产代码中……

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


s display as:  0.00021

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

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

它的最短形式是这样的:

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

NaN和无限值必须额外检查,所以它的完整形式如下:

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


return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}

这也可以复制/粘贴,以很好地与Float一起工作。

对于Java 7及以下版本,这将导致"0.0"对于任何零值double,所以你需要添加:

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

我需要将一些double转换为货币值,发现大多数解决方案都是可以的,但不适合我。

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

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

如果是小数,就只能得到两个小数。

我想每个人的想法都是对的,但并非所有的答案都是直截了当的。 我认为这是一段非常有用的代码。下面是一个将工作的片段:

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

".8"是你设置你想要显示的小数点后数位的地方。

我正在使用Eclipse,它工作没有问题。

希望这对你有帮助。我将感激任何反馈!

对于由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, this is the best
DecimalFormat df =
new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
return df.format(d);
}
}


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

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() )
}
< p >我的解决方案: 字符串str =字符串。格式(“%。0 f”,yourDouble); < / p >

这可能是一个切线....但如果你需要把一个数值作为一个整数(太大而不能成为一个整数)放入一个序列化器(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

使用String.format ("%.0f", number)

%。0f表示0小数

String numSring = String.format ("%.0f", firstNumber);
System.out.println(numString);

这不仅适用于整数:

double dexp = 12345678.12345678;
BigDecimal bigDecimal = new BigDecimal(Double.toString(dexp));
System.out.println("dexp: "+ bigDecimal.toPlainString());

这对我很有用。输出将是一个字符串。

String.format("%.12f", myvalue);

转换科学符号的好方法

String.valueOf(YourDoubleValue.longValue())