Snippet IT IT News, Programming, Internet and Blogging

20Mar/091

Java: Format integer into number of decimal places and performance

ADVERTISEMENTS

For certain reasons (e.g. precision issue), some programmer may store a float value (e.g. money) in integer variable. For example -12345678.90 is stored as -1234567890. To convert the integer value to number with number of decimal places is a problem.

There are several way to do it. You can simply use the Java's String.format(), DecimalFormat or Float.toString(). Most of them does not meet my requirements: Simple, fast, precise and with thousand separator. Therefore I wrote a simple class that ease myself.

public class MyFormat {
    public static String format(int value, int nodp) {
        int mod;
        StringBuilder str;
        char[] stack;
        int i;
        boolean negative;
        boolean firstZero;
        int comma;

        negative = false;
        if (value<0) {
            negative = true;
            value = -value;
        }

        stack = new char[15];
        i = stack.length;
        str = new StringBuilder();
        while (nodp > 0) {
            mod = value % 10;
            value = value / 10;
            stack[--i] = (char) ('0' + mod);
            nodp--;
        }
        stack[--i] = '.';
        firstZero = true;
        comma = 0;
        while (firstZero || value > 0) {
            mod = value % 10;
            value = value / 10;
            stack[--i] = (char) ('0' + mod);
            firstZero = false;
            comma ++;
            if (comma == 3) {
                comma = 0;
                if (value > 0)
                    stack[--i] = ',';
            }
        }
        if (negative) str.append('-');
        while(i< stack.length) {
            str.append(stack[i++]);
        }

        return str.toString();
    }
}


I also wrote a test program to test it's performance and precision. The test program runs 100,000 loops for each format method and print out the formatted value. Here is the test program:

public class Test {
    public static void main(String[] args) {
        long start;
        long end;
        int loop = 100000;
        int value = -1234567890;
        int i;        

        // Use String.format
        Integer integral = value/100;
        Integer frag = value>0?value%100:-value%100;
        start = System.currentTimeMillis();
        for (i = 0; i < loop; i++)
            String.format("%d.%02d", integral, frag);
        end = System.currentTimeMillis();

        System.err.println("1. String format: " + (end-start) + "ms");
        System.err.println("1. String format: " + String.format("%d.%02d", integral, frag));

        // Use DecimalFormat
        DecimalFormat df;
        float fvalue = value/100.0f;
        df = new DecimalFormat("0.00");
        df.setGroupingUsed(true);
        df.setGroupingSize(3);
        start = System.currentTimeMillis();
        for (i = 0; i < loop; i++)
            df.format(fvalue);
        end = System.currentTimeMillis();

        System.err.println("2. DecimalFormat format: " + (end-start) + "ms");
        System.err.println("2. DecimalFormat format: " + df.format(fvalue));

        // User Float.toString
        start = System.currentTimeMillis();
        for (i = 0; i < loop; i++)
            Float.toString(fvalue);
        end = System.currentTimeMillis();

        System.err.println("3. Float.toString format: " + (end-start) + "ms");
        System.err.println("3. Float.toString format: " + Float.toString(fvalue));

        // Use my own format
        start = System.currentTimeMillis();
        for (i = 0; i < loop; i++)
            MyFormat.format(value, 2);
        end = System.currentTimeMillis();

        System.err.println("4. My format: " + (end-start) + "ms");
        System.err.println("4. My format: " + format(value, 2));
    }
}

And this is the result:

1. String.toString format: 634ms
1. String.toString format: -12345678.90
2. DecimalFormat format: 322ms
2. DecimalFormat format: -12,345,679.00
3. Float.toString format: 54ms
3. Float.toString format: -1.2345679E7
4. My format: 60ms
4. My format: -12,345,678.90

The results shows that my program is 10 times faster than String.format, 5 times faster than DecimalFormat and as fast as Float.toString.

The String.format way shows the result I wanted but it is too slow and unexceptable.

The DecimalFormat way shows the inprecise value (-12,345,679.00) and it is slow too.

The Float.toString way  shows the inprecise value and it is not the format I wanted.

Related Articles

Comments (1) Trackbacks (1)
  1. impressed!!!


Leave a comment