-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoundNumber.js
87 lines (75 loc) · 2.13 KB
/
BoundNumber.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { freeze } from './.internal/freeze.js'
import { isNumber } from './.internal/isNumber.js'
import { makeInstanceOf } from './makeInstanceOf.js'
import { Interval } from './Interval.js'
/**
* Create a number that has an upper an lower bound.
*
* @arg {number} value - The number.
* @arg {number} min - The lower bound. The value will never fall below this number.
* @arg {number} max - The upper bound. The value will never rise above this number.
*
* @also
*
* @arg {number} value - The number.
* @arg {Interval|object} interval - An object that has a `min` and `max` property.
*
* @return BoundNumber
*/
function BoundNumber () {
if (!(this instanceof BoundNumber)) {
return makeInstanceOf(BoundNumber, arguments)
}
var args = Array.prototype.slice.call(arguments)
var head = args.slice(0, 1)
var tail = args.slice(1)
var interval = parseInterval(tail)
var value
if (isNumber(head[0]) && interval.min <= head[0] && head[0] <= interval.max) {
value = head[0]
} else if (isFinite(interval.min)) {
if (isNumber(head[0])) {
value = head[0] < interval.min ? interval.min : interval.max
} else {
value = interval.min
}
} else {
value = null
}
this.value = value
this.min = interval.min
this.max = interval.max
Object.defineProperty(this, '_interval', {
value: interval
})
freeze(this, BoundNumber)
}
BoundNumber.prototype.has = function (n) {
return this._interval.has(n)
}
BoundNumber.prototype.project = function () {
var v
var a = this
var b = parseInterval(arguments)
if (a.min === b.min && a.max === b.max) {
return this
} else {
v = ((a.value - a.min) * (b.max - b.min) / (a.max - a.min)) + b.min
return BoundNumber(v, b)
}
}
BoundNumber.prototype.valueOf = function () {
return this.value
}
function parseInterval (args) {
if (args.length === 2) {
return Interval(args[0], args[1])
} else if (args.length === 1 && args[0] instanceof Interval) {
return args[0]
} else if (args.length === 1 && typeof args[0] === 'object') {
return Interval(args[0].min, args[0].max)
} else {
return Interval()
}
}
export { BoundNumber }