I have the below code
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);
The double Value which I set is not returned as output.
Double Value using Big Decimal 78871234510124576
Double Value using String format 78871234510124576
Is there a standard way to convert a Double
to a String
without explicit type casting with the range of value being long
data type (max value) instead of double
?
My Intention of asking this question is because am reading an excel sheet using Apache POI with all cell type being general in the Excel. I am using getNumericCellValue()
to read the value of a cell which always returns number in decimal format. For example 222 will be returned as 22.0. I want to remove the decimal and convert it to a String.
Essentially, the root cause of your issue is when you get the double
from POI:
Cell myCell = ... ;
double cellValue = myCell.getNumericCellValue();
There, cellValue
would already have the same internal representation for both 78871234510124568.0
and 78871234510124576.0
(and at least all numbers inbetween):
System.err.println(Double.doubleToRawLongBits(78871234510124568.0));
System.err.println(Double.doubleToRawLongBits(78871234510124576.0));
Output:
4859809850462277474
4859809850462277474
This is simply a matter of how floating point values are stored in memory. There are just not enough bits available to distinguish between these numbers. See What Every Computer Scientist Should Know About Floating-Point Arithmetic and IEEE floating point for more information.
If you need a higher accuracy, you must retrieve the value as a String
and then use the String
for further processing, like parsing it into a BigDecimal
:
Cell myCell = ... ;
String cellValue = myCell.getStringCellValue();
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
df.setParseBigDecimal(true);
BigDecimal value = (BigDecimal) df.parse(cellValue);
You need to consider the proper locale, so that the decimal point is treated correctly (.
vs. ,
). Locale.US
uses .
.
When you convert a large number to a double
you will lose some information. You can only put back that information if your either
One way this is done with doubles is to have two doubles. One with the main values and one with the error.
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);
prints
cellValue=7.8871234510124576E16 err=-8.0 original=78871234510124568
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With