51

I want to return the number as long as it falls within a limit, else return the maximum or minimum value of the limit. I can do this with a combination of Math.min and Math.max.

public int limit(int value) {
    return Math.max(0, Math.min(value, 10));
}

I'm wondering if there's an existing limit or range function I'm overlooking.
3rd party libraries welcome if they are pretty common (eg: Commons or Guava)

TylerH
  • 20,799
  • 66
  • 75
  • 101
Sean Connolly
  • 5,692
  • 7
  • 37
  • 74
  • Why is this necessary if `Math.min` `Math.max` provides your solution? – Robadob Jul 29 '13 at 20:24
  • 5
    That is the appropriate pattern. If you do this in a lot of places, just define your own method in a helper class. – Jim Garrison Jul 29 '13 at 20:24
  • 4
    If this code seems too long, just wrap it in your own function. – Robert Harvey Jul 29 '13 at 20:24
  • 4
    I'm coming to the community to see if such a function already exists. Just a question.. I don't think it's a bad question? – Sean Connolly Jul 29 '13 at 20:28
  • It's a rather trivial question, but nobody has voted to close it yet. – Robert Harvey Jul 29 '13 at 20:31
  • 1
    Not a bad question. You show what have done so far and you ask specifically if there is a one method solution. No one wants to appear ignorant by reinventing the wheel when a simpler solution exists. Not sure why it was downvoted, but I +1'ed to help counter it. – Trevor Freeman Jul 29 '13 at 20:43
  • 1
    @RobertHarvey I was wondering the same thing. It seems really straightforward. I guess it's a just something mathematicians would expect to be already built in the math library. – But I'm Not A Wrapper Class May 13 '14 at 17:31
  • There's no really better way to do this in the C-based languages, short of a defined function. Depending on your preferences you may use min/max, may code one or two `if` statements, etc. None of these is inherently the "right" or "wrong" way. – Hot Licks May 13 '14 at 18:09

7 Answers7

31

OP asks for this implementation in a standard library:

int ensureRange(int value, int min, int max) {
   return Math.min(Math.max(value, min), max);
}

boolean inRange(int value, int min, int max) {
   return (value>= min) && (value<= max);
}

A pity the standard Math library lacks these

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Barry Staes
  • 3,890
  • 4
  • 24
  • 30
  • 2
    Also, the C-based languages lack the obvious idiom `(min <= value <= max)`, much to the consternation of newbies. – Hot Licks May 13 '14 at 18:24
  • 2
    I think that ensureRange should be other way around: `int ensureRange(int value, int min, int max) { return Math.min(Math.max(value, min), max); }` That's a good reason to have it in a library. So you can have it wrong only once ;-) – Renso Lohuis May 14 '14 at 16:45
  • @RensoLohuis Trivial: I wanted `min` executed before `max`. Read order != Execution order. – Barry Staes May 15 '14 at 07:21
  • 1
    @BarryStaes I am not talking about execution order. You have Math.min(value, min), this will not help you to ensure the range. if the value = 3 and min = 5, Math.min will return 3, so it will not stay inside range. The same goes for Math.max(value, max). So this function will not ensure range. – Renso Lohuis Jun 30 '14 at 13:20
  • @RensoLohuis thanks good catch! Pardon my brainfart, fixed now. – Barry Staes Jun 30 '14 at 13:30
16

I understand this was asked for Java. In Android world, it's common to use Kotlin and Java combined. In case some Kotlin user reached here (just like me), then they can use coerceIn extension function:

Kotlin Code:

println(10.coerceIn(1, 100)) // 10
println(10.coerceIn(1..100)) // 10
println(0.coerceIn(1, 100)) // 1
println(500.coerceIn(1, 100)) // 100

Read more on official Kotlin Documentation.

HBB20
  • 2,743
  • 1
  • 24
  • 35
15

As of version 21, Guava includes Ints.constrainToRange() (and equivalent methods for the other primitives). From the release notes:

added constrainToRange([type] value, [type] min, [type] max) methods which constrain the given value to the closed range defined by the min and max values. They return the value itself if it's within the range, the min if it's below the range and the max if it's above the range.

Copied from https://stackoverflow.com/a/42968254/122441 by @dimo414.

Unfortunately this version is quite recent as of July 2017, and in some projects (see https://stackoverflow.com/a/40691831/122441) Guava had broken backwards compatibility that required me to stay on version 19 for now. I'm also shocked that neither Commons Lang nor Commons Math has it! :(

Hendy Irawan
  • 20,498
  • 11
  • 103
  • 114
13

If you're on Android, use the MathUtils (in support library), it has only one function which specifically does this called clamp.

This method takes a numerical value and ensures it fits in a given numerical range. If the number is smaller than the minimum required by the range, then the minimum of the range will be returned. If the number is higher than the maximum allowed by the range then the maximum of the range will be returned.

usernotnull
  • 3,480
  • 4
  • 25
  • 40
5

The Math.max(int a, int b) function is defined as:

public static int min(int a, int b) {
    return (a <= b) ? a : b;
}

So you can make a combination of the max and min functions as follows:

private static int MAX=10;
private static int MIN=0;

public int limit(int a) {
    return (a > MAX) ? MAX : (a < MIN ? MIN: a );
}
Majid Laissi
  • 19,188
  • 19
  • 68
  • 105
4

Generic method for any class implementing Comparable (including Number and its sub-classes):

public static <T extends Comparable<? super T>> T limit(T o, T min, T max){
    if (o.compareTo(min) < 0) return min;
    if (o.compareTo(max) > 0) return max;
    return o;
}

The only requirement is that all arguments must be of the same class. It prevents possible type conversion loss. In fact it is incorrect to compare float with double of long with int etc. For example (double) 0.1 != (float) 0.1.

Usage:

double x = 13.000000001;
x = limit(x, 12.0, 13.0);
System.out.println("x = " + x); //x = 13.0

Unfortunately it is impossible to change the first argument directly by just limit(x, 12.0, 13.0) because primitive types are immutable.

adam_0
  • 6,920
  • 6
  • 40
  • 52
Oleg Mikhailov
  • 5,751
  • 4
  • 46
  • 54
-5

You do not need an external library for this, try this test case:

public class RandomNumber {

    public static void main(String[] Args) {
        System.out.println("random = " + randomInRange(5,10));
    }
    
    public static double randomInRange(double arg1, double arg2) {
        double my_number = Math.ceil(Math.random() * (arg1 - arg2) + arg2);
        return my_number;
    }

}
aboger
  • 2,214
  • 6
  • 33
  • 47
RedBirdISU
  • 79
  • 1
  • 4