79

Suppose I have a value, I usually do this to "clamp" it to a range, here the range [0..1]. That is if it is below the range start, increase it to the range start, it above the range end, reduce it to the range end.

clampedValue = Math.max(0, Math.min(1, value));

Is there any built in function for clamping to a range?

Amro
  • 123,847
  • 25
  • 243
  • 454
weston
  • 54,145
  • 21
  • 145
  • 203
  • @LuiggiMendoza [HLSL](http://en.wikipedia.org/wiki/High-level_shader_language) – weston May 20 '13 at 19:12
  • See http://stackoverflow.com/questions/2683442/where-can-i-find-the-clamp-function-in-net ? – Adam Gent May 20 '13 at 19:13
  • 1
    @LuiggiMendoza Also [OpenGL](http://www.opengl.org/sdk/docs/manglsl/xhtml/clamp.xml) – weston May 20 '13 at 19:13
  • @AdamGent thanks, but that's c# – weston May 20 '13 at 19:14
  • @weston it looks pretty trivial to write your own (ie just translate the c#). – Adam Gent May 20 '13 at 19:16
  • 1
    @AdamGent It's clearly trivial to right my own function, I have the code right in the question there. I'd rather use one that's built in, particularly because that would deal with all value datatypes probably. – weston May 20 '13 at 19:18
  • 3
    I don't really know your level of expertise java so it's hard for me to assume your knowledge. The c # uses Comparable to handle multiple data types.... Guess what you do in Java :) – Adam Gent May 20 '13 at 19:22

7 Answers7

200

Is there any built in function for clamping to a range?

No.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 2
    For future visitors: this is changing. See [Michael Berry's answer](https://stackoverflow.com/a/75707634/4151129). – Ben I. Aug 22 '23 at 15:45
56

Having looked at the generic clamp method offered up in another answer, it is worth noting that this has boxing/unboxing considerations for primitive types.

public static <T extends Comparable<T>> T clamp(T val, T min, T max) {...}

float clampedValue = clamp(value, 0f, 1f);

This will use the Float wrapper class, resulting in 3 box operations, one for each parameter, and 1 unbox operation for the returned type.

To avoid this, I would just stick to writing it long hand or use a non-generic function for the type you want:

public static float clamp(float val, float min, float max) {
    return Math.max(min, Math.min(max, val));
}

Then just overload with identical methods for every primitive type you require.

wcmatthysen
  • 445
  • 4
  • 19
weston
  • 54,145
  • 21
  • 145
  • 203
27

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.

dimo414
  • 47,227
  • 18
  • 148
  • 244
  • 3
    For those that use Apache commons lang3 and not Guava, there is the Range.fit method. `Range.between(0.0, 1.0).fit(0.5); // returns 0.5` – Marty Neal Jul 07 '20 at 20:48
  • They added this in 3.10: https://commons.apache.org/proper/commons-lang/changes-report.html#a3.10 – jgibson Jul 20 '20 at 21:04
17

Ported from a .NET answer:

public static <T extends Comparable<T>> T clamp(T val, T min, T max) {
    if (val.compareTo(min) < 0) return min;
    else if (val.compareTo(max) > 0) return max;
    else return val;
}

Caution: Unlike .NET, primitive types are not allowed in generics, which means they must be boxed/unboxed. When working with primitive types, such as int and double, this implementation will perform three box operations and one unbox operation.

Note: since it’s a port of the .NET answer, I made this a community wiki post.

Community
  • 1
  • 1
Adam Gent
  • 47,843
  • 23
  • 153
  • 203
12

Another not so pretty, but possible solution is to use the ternary operator, which is a shorthand for the if-then-else statement.

Some Examples:

// value must be between MIN_VALUE and MAX_VALUE
value = value > MAX_VALUE ? MAX_VALUE : value < MIN_VALUE ? MIN_VALUE : value;

// value must be between 0 and 10
value = value > 10 ? 10 : value < 0 ? 0 : value;
HugoTeixeira
  • 4,674
  • 3
  • 22
  • 32
  • 1
    I like this one-liner. It's concise! – JSong Oct 18 '18 at 06:52
  • 2
    I ran several thousand iterations of this, versus the original method provided by @weston and this seems to be taking about 3/4ths of the time to calculate. Definitely more efficient than using Min/Max functions. – Fire 'N Lightnin' May 12 '22 at 16:54
6

There will be a new built-in method to do just this in Java 21.

Overloads are provided for float, double, int and long.

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
1

This may be unrelated to the question, but if someone's looking for the same feature in javafx or kotlin, as I was, here they are:

javafx:

Utils.clamp(min, value, max)

kotlin:

value.coerceIn(min, max)
mXaln
  • 105
  • 11