-
Notifications
You must be signed in to change notification settings - Fork 0
/
number.js
292 lines (256 loc) · 7.57 KB
/
number.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/*jshint laxcomma: true, smarttabs: true*/
/*globals module,process,require,exports,__dirname,__filename */
'use strict';
/**
* Number utilities for the standard lib
* @module gaz/number
* @author Eric Satterwhite
* @since 0.1.0
* @requires mout/number
* @requires mout/math
*/
var mnumber = require('mout/number')
,mmath = require('mout/math')
;
/**
* Ensures a number is with in an allowable range
* @param {Number} num The number to check
* @param {Number} min The lower bounds of the limit
* @param {Number} max The upper bounds of the limit
* @returns {Number} will return num if it is with the the range, other wise it will return either the min or max
* @example number = require('gaz/number')
number.limit( 100, 0, 10 ) // 10
number.limit( 8, 0, 10 ) // 8
})
*/
exports.limit = function(num, min, max ){
return Math.min( max, Math.max( min, num ));
};
/**
* Rounds a number to a give precision
* @param {Number} num The number to round
* @param {Number} precision The number of decimal places to round the number to
* @returns {Number} The resultant number
* @example number = require('gaz/number')
number.round( 3.14588930520, 2 ) // 3.15
*/
exports.round = function( num, precision ){
num = parseFloat( num );
precision = Math.pow( 10, precision || 0).toFixed( precision < 0 ? -precision:0 );
return Math.round( num * precision )/precision;
};
/**
* executes a fucntion X many times passing the number in as a param
* @param {Number} num The number of times to execute the functoin
* @param {Function} fn The function to execute will be passed: </br>
* * count- the count of how many time the function has been executed
* * num - the original number passed in
* @param {Object} bind The object in whose context to execute the function
*
*/
exports.times = function( num, fn, bind ){
for( var i =0; i< num; i++){
fn.call( bind, i, num );
}
};
/**
* Generates a random number within a given range
* @param {Number} The lower bounds of the random number
* @param {Number} The upper bounds of the random number
* @return {Number} A random Number
* @example number = require('gaz/number')
number.random( 0, 1000 ) // 845
*/
exports.random = function( min, max ){
min = min || 0;
max = max || 1000000;
return Math.floor( Math.random() * ( max - min + 1 ) + min );
};
/**
* Attempts to generate a number from a passed in string
* @param {String} The string to pase
* @returns {Number} A number if one was created, otherwise it will return null
* @example number = require('gaz/number')
number.from( "12.43" ) // 12.43
*/
exports.from = function( item ){
var n = parseFloat( item );
return isFinite( n ) ? n : null;
};
/**
* Formats a number
* @param {Number} num The Number to format
* @options {Object} options Config object used to format the number</br>
<ul>
<li>decimal - decimal separator</li>
<li>group - thousands separator</li>
<li>decimals - number of decimals</li>
<li>precision - number of significant numbers </li>
<li>scientific - set to false if 1.4e+4 notation should be replaces by 14000</li>
<li>suffix - string to be prepended</li>
<li>prefix - string to be appended</li>
</ul>
* @returns {String} A string formated as specified
* @example number = require('gaz/number')
console.log( number.format( 100, { decimals:2, group:",", decimal:"."} ) ) // 100.00
*/
exports.format = function( num, options ){
var getOption
,value
,negetive
,prefix
,suffix
,index
,decimal
,decimals
,group
,precision
,modifyers
,x
,key
,match
,zeros
,neg
,newOutput
,i;
getOption = function( key ){
if( options[key] != null ){
return options[key];
}
return "";
};
value = num;
negetive = value < 0;
decimal = getOption('decimal');
precision = getOption('precision');
group = getOption( 'group' );
decimals = getOption( 'decimals' );
modifyers = ['prefix', 'suffix'];
if( negetive ){
neg = getOption( 'negetive' );
neg.prefix = '-';
for( x = 0; x < modifyers.length; x++ ){
key = modifyers[x];
if( neg[key] ){
options[key] = getOption[key] + neg[key];
}
}
value = -value;
}
prefix = getOption( 'prefix' );
suffix = getOption( 'suffix' );
if( decimals !== '' && decimals >= 0 && decimals <= 20){
value = value.toFixed( decimals );
}
if( precision >= 1 && precision <= 2 ){
value = (+value).toPrecision(precision);
}
value +="";
if( getOption('scientific') === false && value.indexOf('e') > -1 ){
match = value.split('e');
zeros = +match[1];
value = match[0].replace('.', '');
if( zeros < 0 ){
zeros = -zeros -1;
index = match[0].indexOf('.');
if( index > -1 ){
zeros -= index -1;
while( zeros--){
value = '0' + value;
}
value ='0.' + value;
} else {
index = match[0].lastIndexOf('.');
if( index > -1 ){
zeros -= match[0].length - index -1;
while( zeros--){
value += '0';
}
}
}
}
}
if( decimal != '.'){
value = value.replace('.', decimal);
}
if (group){
index = value.lastIndexOf(decimal);
index = (index > -1) ? index : value.length;
newOutput = value.substring(index);
i = index;
while (i--){
if ((index - i - 1) % 3 == 0 && i != (index - 1)){
newOutput = group + newOutput;
}
newOutput = value.charAt(i) + newOutput;
}
value = newOutput;
}
if (prefix) {
value = prefix + value;
}
if (suffix){
value += suffix;
}
return value;
};
/**
* Short cut to the format function which attempts to format a number as a US Currency
* @param {Number} num The number to format
* @param {Number} decimals The number of decimal palces to honor
* @return {String}
* @example number = require('gaz/number')
number.formatCurrency( 50.115318568 ) // $50.10
*/
exports.formatCurrency = function( num, decimals ){
return exports.format( num, {decimal:'.', decimals:decimals || 2, prefix:'$', group:','});
};
/**
* Short cut to the format function which attempts to format a number as a percentage
* @param {Number} num The number to format
* @param {Number} decimals The number of decimal palces to honor
* @return {String}
* @example number = require('gaz/number')
number.formatPercentage( 50.115318568, 1 ) // 50.1%
*/
exports.formatPercentage = function( num, decimals ){
return exports.format( num, {decimal:'.', decimals:decimals || 0, suffix:'%', group:','});
};
exports.getDollars = function(num)
{
return (num / 100).toFixed(2);
};
exports.setCents = function(num)
{
return Math.floor( num * 100 );
};
// General number things
exports.MAX_INT = mnumber.MAX_INT
exports.MAX_SAFE_INTEGER = mnumber.MAX_SAFE_INTEGER
exports.MAX_UINT = mnumber.MAX_UINT
exports.MIN_INT = mnumber.MIN_INT
exports.abbreviate = mnumber.abbreviate
exports.currencyFormat = mnumber.currencyFormat
exports.enforcePrecision = mnumber.enforcePrecision
exports.isNaN = mnumber.isNaN
exports.nth = mnumber.nth
exports.ordinal = mnumber.ordinal
exports.pad = mnumber.pad
exports.rol = mnumber.rol
exports.ror = mnumber.ror
exports.sign = mnumber.sign
exports.toInt = mnumber.toInt
exports.toUInt = mnumber.toUInt
exports.toUInt31 = mnumber.toUInt31
// Math specifics
exports.ceil = mmath.ceil
exports.clamp = mmath.clamp
exports.countSteps = mmath.countSteps
exports.floor = mmath.floor
exports.between = mmath.inRange
exports.isNear = mmath.isNear
exports.lerp = mmath.lerp
exports.loop = mmath.loop
exports.map = mmath.map
exports.norm = mmath.norm
exports.round = mmath.round