66

があるとします。value通常、これを範囲に「クランプ」するためにこれを行います。ここでは range[0..1]です。つまり、範囲の開始を下回っている場合は、範囲の開始まで増やし、範囲の終了を上回っている場合は、範囲の終了まで減らします。

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

範囲にクランプするための組み込み関数はありますか?

4

5 に答える 5

180

範囲にクランプするための組み込み関数はありますか?

いいえ。

于 2013-05-20T19:14:22.530 に答える
51

別の回答で提供されている一般的なクランプ方法を見てきましたが、これにはプリミティブ型のボックス化/ボックス化解除に関する考慮事項があることに注意してください。

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

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

これはFloatラッパー クラスを使用し、3 つのボックス操作 (パラメーターごとに 1 つ)、および返された型に対する 1 つのボックス解除操作になります。

これを避けるために、私はそれを長い手で書くことに固執するか、あなたが望むタイプに非ジェネリック関数を使用します:

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

次に、必要なすべてのプリミティブ型に対して同一のメソッドをオーバーロードします。

于 2013-05-20T22:06:53.490 に答える
17

.NETの回答から移植:

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;
}

注意: .NET とは異なり、ジェネリックではプリミティブ型を使用できません。つまり、ボックス化/ボックス化解除する必要があります。intやなどのプリミティブ型をdouble操作する場合、この実装は 3 つのボックス操作と 1 つのボックス解除操作を実行します。

注: これは .NET answerの移植版であるため、これをコミュニティ wiki 投稿にしました。

于 2013-05-20T19:35:33.813 に答える