我有以下代码
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。
答案 0 :(得分:4)
基本上,问题的根本原因是当您从POI获得double
时:
Cell myCell = ... ;
double cellValue = myCell.getNumericCellValue();
在那里,cellValue
已经为78871234510124568.0
和78871234510124576.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 Arithmetic和IEEE 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());