How to read a double value with a certain precision
How to read a double va开发者_JAVA技巧lue from a String with a certain precision (say 4) assuming the string contains something like "10.1234" using this api
If you want decimal precision, double
is the wrong target type, as it is a binary format that cannot accurately represent most round decimal fractions. That double
value will actually be rounded to something like 10.123399999999999999976
Instead, use BigDecimal
all the way, or forget about runding while you read and manipulate the data, and round it only when you print the result.
Read The Floating-Point Guide for more information.
System.out.println(new Double(new BigDecimal("10.123456789").
setScale(4, BigDecimal.ROUND_DOWN). // choose precision and specify rounding policy
doubleValue()
));
>> run:
10.1234
I assume that your String also contains letters. You can parse the number out of the String first:
String numberString = ...
int precision = ...
int index = numberString.indexOf(".");
numberString = numberString.substring(0, index+precision+1); // Maybe without "+1"
Double number = Double.valueOf(numberString);
You can use regular expression to truncate the String
to at most 4 digits following the decimal point, then use Double.valueOf
.
String[] tests = {
"12",
"12.",
"12.3",
"12.34",
"12.345",
"12.3456",
"12.34567",
"-123.45678",
"1.23456.789.0",
};
for (String test : tests) {
String truncated = test.replaceAll("(\\.\\d{4}).*", "$1");
System.out.printf("%15s %15s %15s%n",
test, truncated, Double.valueOf(truncated)
);
}
This prints:
12 12 12.0
12. 12. 12.0
12.3 12.3 12.3
12.34 12.34 12.34
12.345 12.345 12.345
12.3456 12.3456 12.3456
12.34567 12.3456 12.3456
-123.45678 -123.4567 -123.4567
1.23456.789.0 1.2345 1.2345
How the regex works
It captures a literal .
, followed by up to four digits \d{4}
, into \1
. It also matches everything else that may follow .*
, and replaces the whole thing with $1
(backreference to what \1
captured).
The advantage of this over, say, a simple indexOf
approach is that it works even when there aren't 4 digits, or even when there isn't even a decimal point at all, without requiring special treatment.
See also
- regular-expressions.info
- Java Tutorials/Regular expressions
You can do something like
Math.round(number*100)/100
to get the precision, but this will probably not do what you want due to the internal representation of floats and doubles.
If you really need to work with a fixed number of digits after the decimal point consider using BigDecimal.
For formatting output you can use the C-like printf functionality as decribed in this article. It is not pretty but practical.
精彩评论