4

Suppose I have Long someLong = 1004L. What efficient method can I use to round this down to 1000L? Note that I do not actually know that someLong == 1004L so I can't simply do someLong -= 4L;. I need a generalizable method. I also want the ability to round down to each 5 instead of each 10, for example a function to round to 1005L (since if we're rounding by 5's then it'll round up instead of down).

More examples .. It could be that I have 1926L and I want to round to 5 meaning I need 1925L. Or I need to round to 10 meaning I need 1930L.

peterh
  • 11,875
  • 18
  • 85
  • 108
user2763361
  • 3,789
  • 11
  • 45
  • 81

6 Answers6

7

This is very simple.

If you want to round always down:

Your required formula is:

someLong-someLong%10

It is because someLong%10 is the remainder of someLong divided by 10. If you get this from the original number, you get the downrounded value, which you wanted.

The generalization is also simple: you can use 100, or even 13, if you want.

If you want to rounding in another direction (for example, rounding always up or always to the middle), then first to add something to this number, and then round always down.


If you want to round always up:

Then first you need to first add 9, then round always down.

someLong+9-(someLong+9)%10

If you want to round always to the middle:

...also you want to round to the nearest neightbor. Then you first add the half of the required interval, then round always down. For example, for 10 it is:

someLong+5-(someLong+5)%10
peterh
  • 11,875
  • 18
  • 85
  • 108
2

Try this:

double a=1002l;
double b=a/10;

a=Math.round(b)*10;

System.out.println("Double round of value : "+a);
Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
Raju Sharma
  • 2,496
  • 3
  • 23
  • 41
2

A generic function to round to the nearest multiple of k would be (works for positives only):

public static long round(long toRound, long k) {
    long times = toRound / k;
    long reminder = toRound % k;
    if (reminder < k / 2)  {
        return k * times;
    } else {
        return k * (times + 1);
    }
}

And a branchless variant (reminder < k / 2 => (2 * reminder / k) < 1:

public static long round(long toRound, long k) {
    long times = toRound / k;
    long reminder = toRound % k;
    return k * (times + ((2 * reminder) / k));
}
Danstahr
  • 4,190
  • 22
  • 38
2

If you want to round a value towards the nearest multiple of step using the semantics of BigDecimal.ROUND_HALF_UP (if exactly halfway between two steps, round up), the necessary calculations are:

val += step/2;
val -= val%step;
jarnbjo
  • 33,923
  • 7
  • 70
  • 94
  • 1
    +1 This is a really neat solution. A two line method, whereas other answers require six or seven. (Including mine, now deleted). – Duncan Jones Apr 11 '14 at 13:25
1
myFloor(long n, int m) {
  return n - (n % m);
}


myRound(long n, int m) {
  int i = (n % m) >= (m / 2) ? m : 0;
  return n + i - (n % m);
}

so m could be 10 , 5 , ...

Farvardin
  • 5,336
  • 5
  • 33
  • 54
1

The following example reachs what you need:

public static void main(String[] args) {
    Long n   = 1004L;
    Long n2  = 1005L;

    n = round(n);
    n2 = round(n2);

    System.out.println(n);
    System.out.println(n2);
}

private static Long round(Long n) {
    if (n%10 <=4) {
        return n -=n%10;
    } else {
        return n += (10-n%10);
    }
}
DanW
  • 247
  • 1
  • 9