<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:10.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
span.EmailStyle19
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="en-CH" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">What’s error-prone is not much the clamping logic proper, but the need to check that the [min, max] interval is not empty. IMO, this is what most people will likely
forget.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Thus, I vote for this addition.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Greetings<br>
Raffaello<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:12.0pt;margin-left:36.0pt">
<b><span style="font-size:12.0pt;color:black">From: </span></b><span style="font-size:12.0pt;color:black">core-libs-dev <core-libs-dev-retn@openjdk.org> on behalf of Tagir Valeev <amaembo@gmail.com><br>
<b>Date: </b>Wednesday, 25 January 2023 at 14:42<br>
<b>To: </b>core-libs-dev@openjdk.org <core-libs-dev@openjdk.org><br>
<b>Subject: </b>Math.clamp method?<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt">Hello!<br>
<br>
Quite often it's necessary to clamp a numerical value to a given<br>
range, using the algorithm like this:<br>
int clampedValue = value > max ? max : value < min ? min : value;<br>
or probably<br>
int clampedValue = Math.max(min, Math.min(max, value));<br>
Some examples in wild: [1] [2]<br>
<br>
These "algorithms" are verbose and error-prone. E.g., many years ago<br>
Math.max and Math.min were mixed in Jenkins CI implementation (later<br>
fixed in [3]). Static analyzers like SonarLint even implement a rule<br>
to catch such kind of mistake [4], but it cannot statically find a<br>
mistake if max and min values are not constant.<br>
<br>
Having a library method for this algorithm will make the code more<br>
readable, and robust. Standard libraries of various languages tend to<br>
implement a function that encapsulates this algorithm. E.g., Kotlin<br>
coerseIn [5], C# Math.Clamp [6], Rust num::clamp [7].<br>
<br>
I hereby propose to add a similar method to Java Math class. The<br>
signatures could be:<br>
public static int clamp(int value, int min, int max)<br>
public static long clamp(long value, long min, long max)<br>
public static double clamp(double value, double min, double max)<br>
public static float clamp(float value, float min, float max)<br>
<br>
These methods should additionally check that min is not greater than<br>
max (throwing IllegalArgumentException). Probably IAE should be thrown<br>
as well if either min or max is NaN for floating point methods. It can<br>
be discussed what should happen if the value is NaN (I think returning<br>
NaN would be ok, but throwing an exception is also a possibility).<br>
<br>
I can post CSR and contribute the implementation if Core Library team<br>
members agree that it's a good idea.<br>
<br>
With best regards,<br>
Tagir Valeev.<br>
<br>
[1] <a href="https://github.com/moneymod/moneymod/blob/4d2c7f5be40dbf392e75/src/main/java/wtf/moneymod/client/impl/ui/click/buttons/settings/SliderButton.java#L71">
https://github.com/moneymod/moneymod/blob/4d2c7f5be40dbf392e75/src/main/java/wtf/moneymod/client/impl/ui/click/buttons/settings/SliderButton.java#L71</a><br>
[2] <a href="https://github.com/androidthings/experiment-expression-flower/blob/f0fd6090e0df1659bad/code/app/src/main/java/com/example/androidthings/VideoProcessor.java#L559">
https://github.com/androidthings/experiment-expression-flower/blob/f0fd6090e0df1659bad/code/app/src/main/java/com/example/androidthings/VideoProcessor.java#L559</a><br>
[3] <a href="https://github.com/jenkinsci/jenkins/commit/e00f99251e0b">https://github.com/jenkinsci/jenkins/commit/e00f99251e0b</a><br>
[4] <a href="https://rules.sonarsource.com/java/RSPEC-3065">https://rules.sonarsource.com/java/RSPEC-3065</a><br>
[5] <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/coerce-in.html">
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/coerce-in.html</a><br>
[6] <a href="https://learn.microsoft.com/en-us/dotnet/api/system.math.clamp?view=net-7.0">
https://learn.microsoft.com/en-us/dotnet/api/system.math.clamp?view=net-7.0</a><br>
[7] <a href="https://docs.rs/num/0.2.1/num/fn.clamp.html">https://docs.rs/num/0.2.1/num/fn.clamp.html</a><o:p></o:p></span></p>
</div>
</div>
</body>
</html>