如何使用Java没有科学记数法打印双重值?

我想打印一个没有指数forms的Java的double值。

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

它显示了这个E符号: 1.2345678E7

我想要它像这样打印它: 12345678

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

你可以使用printf()%f

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

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

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

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

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

Java在一个double中防止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.println(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值的某个阈值以上,这个video解释为:computerphile为什么0.1 + 0.2等于0.30000000000001

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

简而言之:

如果你想摆脱尾随零和区域设置问题,那么你应该使用:

 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,否则你可以硬编码它,但是如果你有小的小数,会导致额外的零。 例如:

     double myValue = 0.00000021d; String.format("%.12f", myvalue); //output: 0.000000210000 
  • 通过使用setMaximumFractionDigits(0);%.0f你删除任何小数的精度,这是很好的整数/长整数,但不是双

     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 

    使用英语语言环境可确保您获得小数点分隔符,无论您的程序在哪里运行

为什么使用340,然后为setMaximumFractionDigits

两个原因:

  • setMaximumFractionDigits接受一个整数,但是它的实现有一个DecimalFormat.DOUBLE_FRACTION_DIGITS允许的最大数字,它等于340
  • Double.MIN_VALUE = 4.9E-324所以340数字,你肯定不会围绕你的双精度和宽松

你可以用DecimalFormat来试试。 有了这个类,你在parsing你的数字时非常灵活。
你可以准确地设置你想使用的模式。
以你的情况为例:

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

如果doublevariables在小数点后有精度,则会截断它。

我有另外一个涉及到BigDecimal的toPlainString()的解决scheme,但这次使用javadoc中推荐的String构造函数:

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

看起来像这个最短的forms:

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

对于任何零值的双精度,Pre 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很好地工作。

我需要将一些双重货币转换为货币价值,而且大多数解决scheme都可以,但不适合我。

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(等) – 没有任何小数点。

如果它是十进制的,我只能得到2个十进制数字。

希望这会有所帮助。

以下代码检测提供的号码是否以科学记数法呈现。 如果是这样,它在正常的演示中用最多“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); } 

当我用它作为一个stringinput到一个math.Eval()函数,它需要一个像“x + 20/50”string的我的生产代码中有同样的问题

我看了数百篇文章..最后我因为速度而跟着这个。 并且因为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 

我认为每个人都有正确的想法,但是所有的答案都不是直截了当的。 我可以看到这是一个非常有用的代码。 以下是一些可以工作的片段:

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

".8"是您要设置小数位数的位置。

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

希望这是有帮助的。 我将不胜感激任何反馈!