Fast double to string conversion with given precision

前端 未结 4 1118
遥遥无期
遥遥无期 2021-02-02 17:14

I need to convert double to string with given precision. String.format(\"%.3f\", value) (or DecimalFormat) does the job but benchmarks show that it slow even in com

相关标签:
4条回答
  • 2021-02-02 17:28

    Disclaimer: I only recommend that you use this if speed is an absolute requirement.

    On my machine, the following can do 1 million conversions in about 130ms:

     private static final int POW10[] = {1, 10, 100, 1000, 10000, 100000, 1000000};
    
     public static String format(double val, int precision) {
         StringBuilder sb = new StringBuilder();
         if (val < 0) {
             sb.append('-');
             val = -val;
         }
         int exp = POW10[precision];
         long lval = (long)(val * exp + 0.5);
         sb.append(lval / exp).append('.');
         long fval = lval % exp;
         for (int p = precision - 1; p > 0 && fval < POW10[p]; p--) {
             sb.append('0');
         }
         sb.append(fval);
         return sb.toString();
     }
    

    The code as presented has several shortcomings: it can only handle a limited range of doubles, and it doesn't handle NaNs. The former can be addressed (but only partially) by extending the POW10 array. The latter can be explicitly handled in the code.

    0 讨论(0)
  • 2021-02-02 17:30

    If you need both speed and precision, I've developed a fast DoubleFormatUtil class at xmlgraphics-commons: http://xmlgraphics.apache.org/commons/changes.html#version_1.5rc1

    You can see the code there: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/util/DoubleFormatUtil.java?view=markup

    It's faster than both DecimalFormat/BigDecimal, as fast as Double.toString, it's precise, it's well tested. It's licensed under Apache License 2.0, so you can use it as you want.

    0 讨论(0)
  • 2021-02-02 17:33

    To my knowledge the fastest and most complete implementation is that of Jack Shirazi:

    http://web.archive.org/web/20150623133220/http://archive.oreilly.com/pub/a/onjava/2000/12/15/formatting_doubles.html

    Code: Original implementation is no longer available online (http://archive.oreilly.com/onjava/2000/12/15/graphics/DoubleToString.java). An implementation can be found here: https://raw.githubusercontent.com/openxal/openxal/57392be263b98565738d1962ba3b53e5ca60e64e/core/src/xal/tools/text/DoubleToString.java

    It provides formatted (number of decimals) and unformatted doubleToString conversion. My observation is, that the JDK performance of unformatted conversion dramatically improved over the years, so here the gain is not so big anymore.

    For formatted conversion it still is.

    For benchmarkers: It often makes a big difference which kind of doubles are used, e.g. doubles very close to 0.

    0 讨论(0)
  • 2021-02-02 17:34

    I haven't benchmarked this, but how about using BigDecimal?

    BigDecimal bd = new BigDecimal(value).setScale(3, RoundingMode.HALF_UP);
    return bd.toString();
    
    0 讨论(0)
提交回复
热议问题