问题
I trying to get value from edittext and stored as string. Then it converts to double. While converting up to 7 characters functioning normally but if i try to add more than 7 result is 1.23456789E8. Here is my code
String value = txtData.txtSearch.getText().toString();
// value = "987654321.45"
double amount1 = Double.parseDouble(value);
// amount1 = 9.8765432145E8
double amount2 = 0.05;
double result = (amount1 * amount2) / 100;
// result = 4.3827160725E14
after calculation i got 4.3827160725E14 which is not correct correct answer is 493827.16
How can i get correct value without losing precision?
回答1:
I solved it. i use BigDecimal instead of double now my code is
String value = txtData.txtSearch.getText().toString();
// value = "987654321.45"
BigDecimal amount1 = new BigDecimal(value);
// amount1 = "987654321.45"
BigDecimal amount2 = new BigDecimal(0.05);
BigDecimal result = (amount1.multiply(amount2)).divide(new BigDecimal(100));
result = result.setScale(2, RoundingMode.FLOOR);
// result = 493827.16
回答2:
The following code gives your expected result:
public class DoubleTest {
public static void main(String[] args) {
double amount1 = Double.parseDouble("987654321.45");
double amount2 = 0.05;
double result = (amount1 * amount2) / 100;
System.out.println(result);
}
}
So, are you sure that you're getting the value that you think you are from txtData.txtSearch.getText().toString(); ?
By the way, if you're really interested in arbitrary precision (e.g. when dealing with money), use BigDecimal.
回答3:
try this:
double result = (amount1 * amount2) / 100.0;
string resultInMyFormat = new DecimalFormat("#.#").format(result);
回答4:
How do you avoid exponential in string to double conversion?
I think we are all missing the point here.
Here is your example:
// value = "987654321.45"
double amount1 = Double.parseDouble(value);
// amount1 = 9.8765432145E8
Presumably, the stuff in comments was printed; e.g. using a debugger or calls to println.
So why are you seeing exponential / scientific notation?
Well it is NOT due to the way that the string was parsed to a double. It is actually happening when the double is converted back to a string in order to print it. Example:
$ cat Test.java
import java.text.DecimalFormat;
public class Test {
public static void main(String[] args) {
String value = "987654321.45";
double amount = Double.parseDouble(value);
System.out.println(amount);
DecimalFormat format = new DecimalFormat("0.########");
System.out.println(format.format(amount));
}
}
$ java Test
9.8765432145E8
987654321.45
See? I started with "987654321.45", converted it to a double. Then printed it two different ways. And got two different string representations for the same double value
So why does println(double) print the number like that?
Well ...
System.outis aPrintStreamprintln(double)is equivalent toprint(double)followed byprintln()print(double)converts thedoubleto aStringusingString.valueOf(double)valueOf(double)returns the same representation asDouble.toString(double)toString(double)is specified to use scientific notation if the magnitude of the number is less than 10-3 or greater or equal to 107.
This is all specified in the respective javadocs. The most salient is the javadoc for toString(double).
If you don't believe me, you can check the Java Language Specification, and the IEE 754 Standard for floating point representations; see Wikipedia.
If you want to, you can even use Double.doubleToRawLongBits(double) to examine the bit representation of a double value.
Finally
After calculation i got
4.3827160725E14which is not correct correct answer is493827.16.
When I repeat that calculation I get the answer 493827.1607250001 ... using System.out.println(double). (Note that there is no scientific notation ... because the number is less than 107. )
The exact answer for the calculation (1987654321.45 * 0.05) / 100 493827.160725. The difference between the the exact answer and what Java gives us is caused by computer floating point rounding error . It happens because the IEE 754 representation is actually binary representation with a binary mantissa and a binary exponent, and because the mantissa has a fixed number of binary digits of precision.
This rounding error is inherent to calculations using IEE 754 representations. If you want to mitigate it, you can use BigDecimal to represent your numbers. But you should be aware that even BigDecimal is not precise:
You can't represent Pi or any other irrational number precisely using
BigDecimal.Many rational numbers don't have a precise representation as a
BigDecimal; e.g. the value of 1.0 / 3.0.
So you still (in theory) need to be concerned with rounding errors with BigDecimal.
来源:https://stackoverflow.com/questions/19970422/android-avoid-exponential-in-string-to-double-conversion