开发者

How to read a double value with a certain precision

开发者 https://www.devze.com 2023-01-02 10:50 出处:网络
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 apiIf you want decimal precision, double is

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号