Skip to content

Commit d102ead

Browse files
committed
#101 Add clamp method
1 parent ac07113 commit d102ead

File tree

6 files changed

+157
-24
lines changed

6 files changed

+157
-24
lines changed

decimal.js

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
/*
132132
* absoluteValue abs
133133
* ceil
134+
* clampedTo clamp
134135
* comparedTo cmp
135136
* cosine cos
136137
* cubeRoot cbrt
@@ -212,6 +213,26 @@
212213
};
213214

214215

216+
/*
217+
* Return a new Decimal whose value is the value of this Decimal clamped to the range
218+
* delineated by `min` and `max`.
219+
*
220+
* min {number|string|Decimal}
221+
* max {number|string|Decimal}
222+
*
223+
*/
224+
P.clampedTo = P.clamp = function (min, max) {
225+
var k,
226+
x = this,
227+
Ctor = x.constructor;
228+
min = new Ctor(min);
229+
max = new Ctor(max);
230+
if (!min.s || !max.s || min.gt(max)) return new Ctor(NaN);
231+
k = x.cmp(min);
232+
return k < 0 ? min : x.cmp(max) > 0 ? max : new Ctor(x);
233+
};
234+
235+
215236
/*
216237
* Return
217238
* 1 if the value of this Decimal is greater than the value of `y`,
@@ -2445,18 +2466,6 @@
24452466
};
24462467

24472468

2448-
/*
2449-
// Add aliases to match BigDecimal method names.
2450-
// P.add = P.plus;
2451-
P.subtract = P.minus;
2452-
P.multiply = P.times;
2453-
P.divide = P.div;
2454-
P.remainder = P.mod;
2455-
P.compareTo = P.cmp;
2456-
P.negate = P.neg;
2457-
*/
2458-
2459-
24602469
// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers.
24612470

24622471

@@ -3934,6 +3943,7 @@
39343943
* atan2
39353944
* cbrt
39363945
* ceil
3946+
* clamp
39373947
* clone
39383948
* config
39393949
* cos
@@ -4153,6 +4163,19 @@
41534163
}
41544164

41554165

4166+
/*
4167+
* Return a new Decimal whose value is `x` clamped to the range delineated by `min` and `max`.
4168+
*
4169+
* x {number|string|Decimal}
4170+
* min {number|string|Decimal}
4171+
* max {number|string|Decimal}
4172+
*
4173+
*/
4174+
function clamp(x, min, max) {
4175+
return new this(x).clamp(min, max);
4176+
}
4177+
4178+
41564179
/*
41574180
* Configure global settings for a Decimal constructor.
41584181
*
@@ -4386,6 +4409,7 @@
43864409
Decimal.atan2 = atan2;
43874410
Decimal.cbrt = cbrt; // ES6
43884411
Decimal.ceil = ceil;
4412+
Decimal.clamp = clamp;
43894413
Decimal.cos = cos;
43904414
Decimal.cosh = cosh; // ES6
43914415
Decimal.div = div;

decimal.mjs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ var EXP_LIMIT = 9e15, // 0 to 9e15
127127
/*
128128
* absoluteValue abs
129129
* ceil
130+
* clampedTo clamp
130131
* comparedTo cmp
131132
* cosine cos
132133
* cubeRoot cbrt
@@ -208,6 +209,26 @@ P.ceil = function () {
208209
};
209210

210211

212+
/*
213+
* Return a new Decimal whose value is the value of this Decimal clamped to the range
214+
* delineated by `min` and `max`.
215+
*
216+
* min {number|string|Decimal}
217+
* max {number|string|Decimal}
218+
*
219+
*/
220+
P.clampedTo = P.clamp = function (min, max) {
221+
var k,
222+
x = this,
223+
Ctor = x.constructor;
224+
min = new Ctor(min);
225+
max = new Ctor(max);
226+
if (!min.s || !max.s || min.gt(max)) return new Ctor(NaN);
227+
k = x.cmp(min);
228+
return k < 0 ? min : x.cmp(max) > 0 ? max : new Ctor(x);
229+
};
230+
231+
211232
/*
212233
* Return
213234
* 1 if the value of this Decimal is greater than the value of `y`,
@@ -2441,18 +2462,6 @@ P.valueOf = P.toJSON = function () {
24412462
};
24422463

24432464

2444-
/*
2445-
// Add aliases to match BigDecimal method names.
2446-
// P.add = P.plus;
2447-
P.subtract = P.minus;
2448-
P.multiply = P.times;
2449-
P.divide = P.div;
2450-
P.remainder = P.mod;
2451-
P.compareTo = P.cmp;
2452-
P.negate = P.neg;
2453-
*/
2454-
2455-
24562465
// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers.
24572466

24582467

@@ -3930,6 +3939,7 @@ function truncate(arr, len) {
39303939
* atan2
39313940
* cbrt
39323941
* ceil
3942+
* clamp
39333943
* clone
39343944
* config
39353945
* cos
@@ -4149,6 +4159,19 @@ function ceil(x) {
41494159
}
41504160

41514161

4162+
/*
4163+
* Return a new Decimal whose value is `x` clamped to the range delineated by `min` and `max`.
4164+
*
4165+
* x {number|string|Decimal}
4166+
* min {number|string|Decimal}
4167+
* max {number|string|Decimal}
4168+
*
4169+
*/
4170+
function clamp(x, min, max) {
4171+
return new this(x).clamp(min, max);
4172+
}
4173+
4174+
41524175
/*
41534176
* Configure global settings for a Decimal constructor.
41544177
*
@@ -4382,6 +4405,7 @@ function clone(obj) {
43824405
Decimal.atan2 = atan2;
43834406
Decimal.cbrt = cbrt; // ES6
43844407
Decimal.ceil = ceil;
4408+
Decimal.clamp = clamp;
43854409
Decimal.cos = cos;
43864410
Decimal.cosh = cosh; // ES6
43874411
Decimal.div = div;

doc/API.html

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<li><a href="#Datan2" >atan2</a></li>
7777
<li><a href="#Dcbrt" >cbrt</a></li>
7878
<li><a href="#Dceil" >ceil</a></li>
79+
<li><a href="#Dclamp" >clamp</a></li>
7980
<li><a href="#Dclone" >clone</a></li>
8081
<li><a href="#Dcos" >cos</a></li>
8182
<li><a href="#Dcosh" >cosh</a></li>
@@ -138,6 +139,7 @@
138139
<li><a href="#abs" >absoluteValue </a><span>abs</span> </li>
139140
<li><a href="#ceil" >ceil </a> </li>
140141
<li><a href="#cmp" >comparedTo </a><span>cmp</span> </li>
142+
<li><a href="#clamp" >clampedTo </a><span>clamp</span> </li>
141143
<li><a href="#cos" >cosine </a><span>cos</span> </li>
142144
<li><a href="#cbrt" >cubeRoot </a><span>cbrt</span> </li>
143145
<li><a href="#dp" >decimalPlaces </a><span>dp</span> </li>
@@ -436,6 +438,16 @@ <h5 id="Dceil">ceil<code class='inset'>.ceil(x) <i>&rArr; Decimal</i></code></h5
436438
a.equals(b) // true</pre>
437439

438440

441+
442+
<h5 id="Dclamp">clamp<code class='inset'>.clamp(min, max) <i>&rArr; Decimal</i></code></h5>
443+
<p>
444+
<code>min</code>: <i>number|string|Decimal</i><br />
445+
<code>max</code>: <i>number|string|Decimal</i>
446+
</p>
447+
<p>See <code><a href='#clamp'>clampedTo</a></code>.</p>
448+
<pre>Decimal.clamp(10.1, 0, 10) // '10'</pre>
449+
450+
439451

440452
<h5 id="Dclone">
441453
clone
@@ -1264,6 +1276,28 @@ <h5 id="ceil">ceil<code class='inset'>.ceil() <i>&rArr; Decimal</i></code></h5>
12641276

12651277

12661278

1279+
<h5 id="clamp">clampedTo<code class='inset'>.clamp(min, max) <i>&rArr; Decimal</i></code></h5>
1280+
<p>
1281+
<code>min</code>: <i>number|string|Decimal</i><br />
1282+
<code>max</code>: <i>number|string|Decimal</i>
1283+
</p>
1284+
<p>
1285+
Returns a new Decimal whose value is the value of this Decimal clamped to the range
1286+
delineated by <code>min</code> and <code>max</code>.
1287+
</p>
1288+
<p>
1289+
The return value is not affected by the value of the
1290+
<a href='#precision'><code>precision</code></a> setting.
1291+
</p>
1292+
<pre>
1293+
x = new Decimal(5)
1294+
min = new Decimal(100)
1295+
max = new Decimal(Infinity)
1296+
x.clampedTo(min, max) // '100'
1297+
x.clamp(-10, -0.1) // '-0.1'</pre>
1298+
1299+
1300+
12671301
<h5 id="cmp">comparedTo<code class='inset'>.cmp(x) <i>&rArr; number</i></code></h5>
12681302
<p><code>x</code>: <i>number|string|Decimal</i></p>
12691303
<table>

test/modules/clamp.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
if (typeof T === 'undefined') require('../setup');
2+
3+
T('clamp', function () {
4+
5+
function t(x, min, max, expected) {
6+
//T.assertEqual(expected, new Decimal(x).clampedTo(min, max).valueOf());
7+
T.assertEqual(expected, new Decimal(x).clamp(min, max).valueOf());
8+
//T.assertEqual(expected, Decimal.clamp(x, min, max).valueOf());
9+
}
10+
11+
t('-0', '0', '0', '-0');
12+
t('-0', '-0', '0', '-0');
13+
t('-0', '0', '-0', '-0');
14+
t('-0', '-0', '-0', '-0');
15+
16+
t('0', '0', '0', '0');
17+
t('0', '-0', '0', '0');
18+
t('0', '0', '-0', '0');
19+
t('0', '-0', '-0', '0');
20+
21+
t(0, 0, 1, '0');
22+
t(-1, 0, 1, '0');
23+
t(-2, 0, 1, '0');
24+
t(1, 0, 1, '1');
25+
t(2, 0, 1, '1');
26+
27+
t(0, 0, -1, 'NaN');
28+
t(1, 1, 1, '1');
29+
t(-1, 1, 1, '1');
30+
t(-1, -1, 1, '-1');
31+
t(1, 1, -1, 'NaN');
32+
t(2, 1, 2, '2');
33+
t(3, 1, 2, '2');
34+
t(1, 0, 1, '1');
35+
t(2, 0, 1, '1');
36+
37+
t(Infinity, 0, 1, '1');
38+
t(0, -Infinity, 0, '0');
39+
t(-Infinity, 0, 1, '0');
40+
t(-Infinity, -Infinity, Infinity, '-Infinity');
41+
t(Infinity, -Infinity, Infinity, 'Infinity');
42+
t(Infinity, Infinity, -Infinity, 'NaN');
43+
t(0, Infinity, 0, 'NaN');
44+
t(0, 1, Infinity, '1');
45+
46+
t(0, NaN, 1, 'NaN');
47+
t(0, 0, NaN, 'NaN');
48+
t(NaN, 0, 1, 'NaN');
49+
});

test/test.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
'atanh',
2929
'cbrt',
3030
'ceil',
31+
'clamp',
3132
'clone',
3233
'cmp',
3334
'config',

test/test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ console.log('\n Testing decimal.js\n');
1515
'atanh',
1616
'cbrt',
1717
'ceil',
18+
'clamp',
1819
'clone',
1920
'cmp',
2021
'config',

0 commit comments

Comments
 (0)