简体   繁体   中英

What is the most efficient way to round a float value to the nearest integer in java?

I've seen a lot of discussion on SO related to rounding float values, but no solid Q&A considering the efficiency aspect. So here it is:

What is the most efficient (but correct) way to round a float value to the nearest integer?

(int) (mFloat + 0.5);

or

Math.round(mFloat);

or

FloatMath.floor(mFloat + 0.5);

or something else?

Preferably I would like to use something available in standard java libraries, not some external library that I have to import.

Based on the Q&A's that I think you are referring to, the relative efficiency of the various methods depends on the platform you are using .

But the bottom line is that:

  • the latest JREs have the performance fix for Math.floor / StrictMath.floor , and
  • unless you are doing an awful lot of rounding, it probably doesn't make any difference which way you do it.

References:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            measurementIteration();
        }
    }

    public static void measurementIteration() {
        long s, t1 = 0, t2 = 0;
        float mFloat = 3.3f;
        int f, n1 = 0, n2 = 0;
        for (int i = 0; i < 1E4; i++) {
            switch ((int) (Math.random() * 2)) {
            case 0:
                n1 += 1E4;
                s = System.currentTimeMillis();
                for (int k = 0; k < 1E4; k++)
                    f = (int) (mFloat + 0.5);
                t1 += System.currentTimeMillis() - s;
                break;
            case 1:
                n2 += 1E4;
                s = System.currentTimeMillis();
                for (int k = 0; k < 1E4; k++)
                    f = Math.round(mFloat);
                t2 += System.currentTimeMillis() - s;
                break;
            }
        }
        System.out.println(String.format("(int) (mFloat + 0.5): n1 = %d    -> %.3fms/1000", n1, t1 * 1000.0 / n1));
        System.out.println(String.format("Math.round(mFloat)  : n2 = %d    -> %.3fms/1000", n2, t2 * 1000.0 / n2));
    }
}

Output on Java SE6:

(int) (mFloat + 0.5): n1 = 500410000    -> 0.003ms/1000
Math.round(mFloat)  : n2 = 499590000    -> 0.022ms/1000

Output on Java SE7 (thanks to alex for the results):

(int) (mFloat + 0.5): n1 = 50120000 -> 0,002ms/1000
Math.round(mFloat) : n2 = 49880000 -> 0,002ms/1000

As you can see, there was a huge performance improvement on Math.round from SE6 to SE7. I think in SE7 there is no significant difference anymore and you should choose whatever seems more readable to you.

I should go for Math.round(mFloat) cause it's encapsuling rounding logic in a method (even if it's not your method).

According with its documentation the code you've written is the same that Math.round executes (except it checks border cases).

Anyway what is more important is the time-complexity of your algorithm, not the time for small constant-like things... Except you are programming something that will be invoked millions of times! :D

Edit: I don't know FloatMath. Is it from JDK?

You may benchmark it by using System.currentTimeMillis() . You will see that difference is too little

Simply adding 0.5 will give an incorrect result for negative numbers. See Faster implementation of Math.round? for a better solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM