使用Java标准的Double to String

时间:2016-04-13 08:35:26

标签: java core

我有以下代码

  double cellValue = 78871234510124568.0;

  String cell = new BigDecimal(cellValue).toPlainString(); 
  String b = String.format("%.0f", cellValue);

  System.out.println("Double Value using Big Decimal " + cell);
  System.out.println("Double Value using String format " + b);

我设置的double值不作为输出返回。

  

使用大十进制的双值78871234510124576
  使用字符串格式的双值78871234510124576

是否存在将Double转换为String而没有显式类型转换的标准方法,其值范围为long数据类型(最大值)而不是{{1} }?

我提出这个问题的意图是因为我正在使用Apache POI阅读excel表,其中所有单元格类型在Excel中都是通用的。我正在使用double来读取始终以十进制格式返回数字的单元格的值。例如,222将返回为22.0。我想删除小数并将其转换为String。

4 个答案:

答案 0 :(得分:4)

基本上,问题的根本原因是当您从POI获得double时:

Cell myCell = ... ;
double cellValue = myCell.getNumericCellValue();

在那里,cellValue已经为78871234510124568.078871234510124576.0提供了相同的内部代表(至少所有数字都介于其中):

System.err.println(Double.doubleToRawLongBits(78871234510124568.0));
System.err.println(Double.doubleToRawLongBits(78871234510124576.0));

输出:

4859809850462277474
4859809850462277474

这只是浮点值如何存储在内存中的问题。没有足够的位来区分这些数字。 有关详细信息,请参阅What Every Computer Scientist Should Know About Floating-Point ArithmeticIEEE floating point

如果您需要更高的准确度,则必须将该值检索为String,然后使用String进行进一步处理,例如将其解析为BigDecimal

Cell myCell = ... ;
String cellValue = myCell.getStringCellValue();
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
df.setParseBigDecimal(true);
BigDecimal value = (BigDecimal) df.parse(cellValue);

您需要考虑正确的区域设置,以便正确处理小数点(.,)。 Locale.US使用.

答案 1 :(得分:2)

将大号转换为double时,您将丢失一些信息。如果你的任何一个

,你只能放回那些信息
  • 对错误是什么做出假设。例如四舍五入到小数点后两位。
  • 你知道错误是什么。

使用双打完成的一种方法是拥有两个双打。一个带有主要值,另一个带有错误。

long l = 78871234510124568L;
double cellValue = l;
double err = l - (long) cellValue;

long original = (long) cellValue + (long) err;

System.out.println("cellValue="+cellValue+" err="+err+" original="+original);

打印

cellValue=7.8871234510124576E16 err=-8.0 original=78871234510124568

答案 2 :(得分:1)

您要尝试处理许多精度(有效小数位),您需要避免使用Double

所以,首先你应该检查单元格内容真的有那么多小数位。 (取决于如何输入值。)

如果是,那么您需要从POI获取字符串表示并直接使用它,或者将String值提供给BigDecimal以获取数值。

如果您无法安排POI将高精度值作为String返回,则可能无法成功使用POI,因为它在内部使用double表示数值。因此,在读取数据文件时,相关信息已经丢失。

答案 3 :(得分:0)

您可以使用以下内容:

DecimalFormat amountFormatter = new DecimalFormat("############");
String s = amountFormatter.format(amount.doubleValue());