Last active
December 22, 2015 10:58
-
-
Save Witiko/6462162 to your computer and use it in GitHub Desktop.
An extension to the standard Math.* javascript library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(NaN, Array, Math, Number, undefined) { | |
var funcPointer = { | |
log: Math.log, | |
pow: Math.pow, | |
rng: Math.random | |
}, | |
isNumber = Number.isNumber, | |
isFloat = function(n) { | |
return /\./.test(n); | |
}; | |
// Number.prototype | |
Number.prototype.toFract = function() { | |
var num = this.toString(); | |
if(/e\+/.test(num)) return [this, 1]; | |
var precision = /\d*(\.\d*)?(e-\d*)?/.exec(num), | |
divident, divisor, greatestDivisor; | |
precision = (precision[1] || " ").length - 1 - | |
Number((precision[2] || "" ).substr(1)); | |
greatestDivisor = Math.gCommDiv( | |
(divisor = precision.exp10()), | |
(divident = this * divisor) | |
); | |
return [ | |
divident / greatestDivisor, | |
divisor / greatestDivisor | |
] | |
}; | |
Number.prototype.random = function() { | |
return Math.random(this); | |
}; | |
Number.prototype.getFract = function() { | |
return this - this.floor(); | |
}; | |
Number.prototype.toDMS = function() { | |
return Math.toDMS(this); | |
}; | |
Number.prototype.pow = function(pow) { | |
return pow !== undefined? | |
Math.pow(this, pow): | |
Math.pow(this); | |
}; | |
Number.prototype.log = function(base) { | |
return base !== undefined? | |
Math.log(base, this): | |
Math.log10(this); | |
}; | |
Number.prototype.log10 = function() { | |
return Math.log10(this); | |
}; | |
Number.prototype.ln = function() { | |
return Math.ln(this); | |
}; | |
Number.prototype.lg = function() { | |
return Math.lg(this); | |
}; | |
Number.prototype.exp10 = function(x) { | |
return x !== undefined && | |
isNumber(x) !== true? | |
NaN:(x === undefined? | |
Math.exp10(this): | |
this * Math.exp10(x) | |
); | |
}; | |
Number.prototype.fac = function() { | |
return Math.fac(this); | |
}; | |
Number.prototype.comb = function(k) { | |
return Math.comb(this, k); | |
}; | |
Number.prototype.rt = function(index) { | |
return index !== undefined? | |
Math.rt(this, index): | |
Math.sqrt(this); | |
}; | |
Number.prototype.sqrt = function() { | |
return Math.sqrt(this); | |
}; | |
Number.prototype.abs = function() { | |
return Math.abs(this); | |
}; | |
Number.prototype.round = function() { | |
return Math.round(this); | |
}; | |
Number.prototype.floor = function() { | |
return Math.floor(this); | |
}; | |
Number.prototype.ceil = function() { | |
return Math.ceil(this); | |
}; | |
Number.prototype.sin = function() { | |
return Math.sin(this); | |
}; | |
Number.prototype.asin = function() { | |
return Math.asin(this); | |
}; | |
Number.prototype.cos = function() { | |
return Math.cos(this); | |
}; | |
Number.prototype.acos = function() { | |
return Math.acos(this); | |
}; | |
Number.prototype.atan2 = function(y) { | |
return Math.atan2(this, y); | |
}; | |
Number.prototype.tan = function() { | |
return Math.tan(this); | |
}; | |
Number.prototype.atan = function() { | |
return Math.atan(this); | |
}; | |
Number.prototype.cotg = function() { | |
return Math.cotg(this); | |
}; | |
Number.prototype.acotg = function() { | |
return Math.acotg(this); | |
}; | |
Number.prototype.sec = function() { | |
return Math.sec(this); | |
}; | |
Number.prototype.asec = function() { | |
return Math.asec(this); | |
}; | |
Number.prototype.csc = function() { | |
return Math.csc(this); | |
}; | |
Number.prototype.acsc = function() { | |
return Math.acsc(this); | |
}; | |
Number.prototype.sinh = function() { | |
return Math.sinh(this); | |
}; | |
Number.prototype.asinh = function() { | |
return Math.asinh(this); | |
}; | |
Number.prototype.cosh = function() { | |
return Math.cosh(this); | |
}; | |
Number.prototype.acosh = function() { | |
return Math.acosh(this); | |
}; | |
Number.prototype.tanh = function() { | |
return Math.tanh(this); | |
}; | |
Number.prototype.atanh = function() { | |
return Math.atanh(this); | |
}; | |
Number.prototype.coth = function() { | |
return Math.coth(this); | |
}; | |
Number.prototype.acoth = function() { | |
return Math.acoth(this); | |
}; | |
Number.prototype.sech = function() { | |
return Math.sech(this); | |
}; | |
Number.prototype.asech = function() { | |
return Math.asech(this); | |
}; | |
Number.prototype.csch = function() { | |
return Math.csch(this); | |
}; | |
Number.prototype.acsch = function() { | |
return Math.acsch(this); | |
}; | |
Number.prototype.degToRad = function() { | |
return this / 180 * Math.PI; | |
}; | |
Number.prototype.degToGrad = function () { | |
return this / 0.9; | |
}; | |
Number.prototype.radToDeg = function() { | |
return this * 180 / Math.PI; | |
}; | |
Number.prototype.radToGrad = function() { | |
return this / Math.PI * 200; | |
}; | |
Number.prototype.gradToDeg = function() { | |
return this * 0.9; | |
}; | |
Number.prototype.gradToRad = function() { | |
return this * Math.PI / 200; | |
}; | |
Number.prototype.degAdjust = function() { | |
return (this + 360) % 360; | |
}; | |
Number.prototype.radAdjust = function() { | |
return (this + (2 * Math.PI)) % (2 * Math.PI); | |
}; | |
Number.prototype.gradAdjust = function() { | |
return (this + 400) % 400; | |
}; | |
// Math | |
Math["\u03c0"] = Math.PI; | |
Math["\u03c4"] = Math.TAU = Math.PI * 2; | |
Math.rt = function() { | |
switch(arguments.length) { | |
case 0: return NaN; | |
case 1: | |
return isNumber(arguments[0])?arguments[0].sqrt():NaN; | |
default: | |
return isNumber(arguments[0]) && | |
isNumber(arguments[1])?arguments[0].pow(1 / arguments[1]):NaN; | |
} | |
}; | |
Math.random = function(n) { | |
return funcPointer.rng() * (n || 1); | |
}; | |
Math.toDMS = function(n) { | |
var d = n.floor(), | |
m = (n - d) * 60, | |
s = (m - (m = m.floor())) * 60; | |
return [d, m, s]; | |
}; | |
Math.fib = function(n) { | |
var g = (1 + Math.sqrt(5)) / 2; | |
return Math.round((Math.pow(g,n) - Math.pow(-g,-n)) / Math.sqrt(5)); | |
}; | |
Math.ln = funcPointer.log; | |
Math.cotg = function(x) { | |
return x !== undefined?x.cos() / x.sin():NaN; | |
}; | |
Math.acotg = function(x) { | |
return x !== undefined?Math.PI / 2 - x.atan():NaN; | |
}; | |
Math.sec = function(x) { | |
return x !== undefined?1 / x.cos():NaN; | |
}; | |
Math.asec = function(x) { | |
return x !== undefined?x.acos(1 / x):NaN; | |
}; | |
Math.csc = function(x) { | |
return x !== undefined?1 / x.sin():NaN; | |
}; | |
Math.acsc = function(x) { | |
return x !== undefined?x.asin(1 / x):NaN; | |
}; | |
Math.sinh = function(x) { | |
return x !== undefined?(Math.E.pow(x) - Math.E.pow(-x)) / 2:NaN; | |
}; | |
Math.asinh = function(x) { | |
return x !== undefined?(x + (x.pow(2) + 1).sqrt()).ln():NaN; | |
}; | |
Math.cosh = function(x) { | |
return x !== undefined?(Math.E.pow(x) + Math.E.pow(-x)) / 2:NaN; | |
}; | |
Math.acosh = function(x) { | |
return x !== undefined?(x + (x.pow() - 1).sqrt()).ln():NaN; | |
}; | |
Math.tanh = function(x) { | |
return x !== undefined?x.sinh() / x.cosh():NaN; | |
}; | |
Math.atanh = function(x) { | |
return x !== undefined?0.5 * ((1 + x) / (1 - x)).ln():NaN; | |
}; | |
Math.coth = function(x) { | |
return x !== undefined?x.cosh() / x.sinh():NaN; | |
}; | |
Math.acoth = function(x) { | |
return x !== undefined?0.5 * ((x + 1) / (x - 1)).ln():NaN; | |
}; | |
Math.sech = function(x) { | |
return x !== undefined?1 / x.cosh():NaN; | |
}; | |
Math.asech = function(x) { | |
return x !== undefined?((1 + (1 - x.pow()).sqrt()) / x).ln():NaN; | |
}; | |
Math.csch = function(x) { | |
return x !== undefined?1 / x.sinh():NaN; | |
}; | |
Math.acsch = function(x) { | |
return x !== undefined?(1 / x + (1 + x.pow()).sqrt() / x.abs()).ln():NaN; | |
}; | |
Math.pow = function() { | |
switch(arguments.length) { | |
case 0: return NaN; | |
case 1: | |
if(isNumber(arguments[0])) | |
return funcPointer.pow(arguments[0], 2); | |
else throw err.type; | |
default: | |
return isNumber(arguments[0]) && | |
isNumber(arguments[1])?funcPointer.pow(arguments[0], arguments[1]):NaN; | |
} | |
}; | |
Math.log = function() { | |
switch(arguments.length) { | |
case 0: return NaN; | |
case 1: | |
return isNumber(arguments[0])?arguments[0].log10():NaN; | |
default: | |
return isNumber(arguments[0]) && | |
isNumber(arguments[1])?arguments[1].ln() / arguments[0].ln():NaN; | |
} | |
}; | |
Math.lg = function(x) { | |
if(x === undefined || | |
!isNumber(x)) return NaN; | |
return Math.log(2, x); | |
}; | |
Math.log10 = function(x) { | |
if(x === undefined || | |
!isNumber(x)) return NaN; | |
return Math.log(10, x); | |
}; | |
Math.exp10 = function(x) { | |
if(x === undefined || | |
!isNumber(x)) return NaN; | |
return (10).pow(x); | |
}; | |
Math.fac = function(n) { | |
if(n === undefined || | |
!isNumber(n) || | |
isFloat(n) || | |
n == Infinity || | |
n < 0) return NaN; | |
var result = 1; | |
while(n > 0) result *= n--; | |
return result; | |
}; | |
Math.med = function() { | |
if(arguments.length < 2) return NaN; | |
return arguments.length & 1? | |
arguments[(arguments.length / 2).floor()]: | |
(arguments[arguments.length / 2] + | |
arguments[arguments.length / 2 - 1]) / 2; | |
}; | |
Math.sum = function(sum, index) { | |
if(arguments.length === 0 || | |
!Array.isArray(sum)) return NaN; | |
var result = 0, length = sum.length; | |
index = isNumber(index)?index:0; | |
if(index >= length) return 0; | |
do result += sum[index]; | |
while(++index < length) | |
return result; | |
}; | |
Math.avg = function() { | |
if(arguments.length < 1) return NaN; | |
var sum = 0, count = 0, length = arguments.length; | |
do sum += arguments[count]; while(++count < length) | |
return sum / count; | |
}; | |
Math.avgVar = function() { | |
if(arguments.length < 2) return NaN; | |
var sum = 0, count = 0, length = arguments.length; | |
do sum += arguments[count].pow(); while(++count < length) | |
return sum / length - Math.avg.apply(Math, arguments).pow(); | |
}; | |
Math.avgOffset = function() { | |
return (Math.avgVar.apply(Math, arguments)).sqrt() / | |
Math.avg.apply( Math, arguments); | |
}; | |
Math.gAvg = function() { | |
if(arguments.length < 2) return NaN; | |
var sum = 1, count = 1, length = arguments.length; | |
do { | |
sum *= arguments[count] / arguments[count - 1]; | |
} while(++count < length) | |
return sum.rt(arguments.length); | |
}; | |
Math.hAvg = function() { | |
if(arguments.length < 2) return NaN; | |
var sum = 0, count = 0, length = arguments.length; | |
do { | |
sum += 1 / arguments[count]; | |
} while(++count < length) | |
return 1 / (1 / arguments.length * sum); | |
}; | |
Math.lim = function(f, x, prec) { | |
if(x === undefined || | |
f === undefined || | |
!isNumber(x) || | |
!(f instanceof Function) || | |
x === -Infinity || | |
x === Infinity || | |
(prec !== undefined && | |
(!isNumber(prec) || | |
(prec <= 0)))) | |
return NaN; | |
if(prec === undefined) | |
prec = 1; | |
var dx = (2).pow(-prec + 1), | |
tans = [ | |
f.tanLine(x + dx, prec + 1), | |
f.tanLine(x - dx, prec + 1) | |
], points = [ | |
tans[0] instanceof Function?tans[0](x):NaN, | |
tans[1] instanceof Function?tans[1](x):NaN | |
], results = []; | |
if(!isNaN(points[0])) results.push(points[0]); | |
if(!isNaN(points[1])) results.push(points[1]); | |
return results.avg(); | |
}; | |
Math.diff = function(f, x, diffClass, prec) { | |
if(x === undefined || | |
f === undefined || | |
!isNumber(x) || | |
!(f instanceof Function) || | |
(diffClass !== undefined && | |
(!isNumber(diffClass) || | |
(diffClass <= 0))) || | |
(prec !== undefined && | |
(!isNumber(prec) || | |
(prec <= 0)))) return NaN; | |
if(diffClass === undefined) | |
diffClass = 1; | |
else if(diffClass > 1) { | |
var diff = arguments.callee; | |
return diff(function(x, prec) { | |
return diff(f, x, 1, prec); | |
}, x, diffClass - 1, prec); | |
} if(prec === undefined) prec = 1; | |
else prec = (2).pow(-prec + 1); | |
return Math.avg( | |
f(x, prec) - f(x - prec, prec), | |
-(f(x, prec) - f(x + prec, prec)) | |
) * 1 / prec; | |
}; | |
Math.integrate = function(f, a, b, prec, scale) { | |
if(a === undefined || | |
b === undefined || | |
f === undefined || | |
!isNumber(a) || | |
!isNumber(b) || | |
!(f instanceof Function) || | |
a > b || | |
(prec !== undefined && | |
(!isNumber(prec) || | |
(prec <= 0)))) return NaN; | |
if(prec === undefined) | |
prec = 1; | |
if(scale === undefined) | |
scale = true; | |
var r = (scale?(b - a).pow(): | |
(b - a)) * (2).pow(prec - 1), | |
h = (b - a) / r, | |
result = 0, | |
x = a; | |
do result += h * (f(x) + f(x += h)) / 2; | |
while(x < b) return result.abs(); | |
}; | |
Math.integRot = function(f, a, b, prec, scale) { | |
return f instanceof Function !== false? | |
Math.PI * Math.integrate(function(x) { | |
return f(x).pow(); | |
}, a, b, prec, scale):NaN; | |
}; | |
Math.comb = function(n, k) { | |
if(n === undefined || | |
k === undefined || | |
!isNumber(n) || | |
!isNumber(k) || | |
n < 0 || k < 0 || k > n) | |
return NaN; | |
if(n === k || k === 0) | |
return 1; | |
if(k === 1) | |
return n; | |
return n.fac() / (k.fac() * (n - k).fac()); | |
}; | |
Math.gCommDiv = function(a, b) { | |
if(a === undefined || | |
b === undefined || | |
!isNumber(a) || | |
!isNumber(b)) | |
return NaN; | |
var length; | |
if((length = arguments.length - 1) > 1) { | |
var results = []; | |
for(var index = 0; index < length; index++) { | |
results.push( | |
Math.gCommDiv( | |
arguments[index], | |
arguments[index + 1] | |
) | |
); | |
} | |
return Math.gCommDiv.apply(Math, results); | |
} else { | |
a = a.abs(); b = b.abs(); | |
var divident = Math.max(a, b), | |
divisor = Math.min(a, b), | |
quotient = (divident / divisor).floor(), | |
remainder = divident % divisor; | |
while(remainder) { | |
divident = divisor; | |
divisor = remainder; | |
remainder = divident % divisor; | |
} return divisor; | |
} | |
}; | |
Math.lCommMul = function(a, b) { | |
if(a === undefined || | |
b === undefined || | |
!isNumber(a) || | |
!isNumber(b)) | |
return NaN; | |
var length; | |
if((length = arguments.length - 1) > 1) { | |
var results = []; | |
for(var index = 0; index < length; index++) { | |
results.push( | |
Math.lCommMul( | |
arguments[index], | |
arguments[index + 1] | |
) | |
); | |
} | |
return Math.lCommMul.apply(Math, results); | |
} else return (a * b).abs() / Math.gCommDiv(a, b); | |
}; | |
// Array.prototype | |
Array.prototype.avg = function() { | |
return Math.avg.apply(Math, this); | |
}; | |
Array.prototype.avgVar = function() { | |
return Math.avgVar.apply(Math, this); | |
}; | |
Array.prototype.avgOffset = function() { | |
return Math.avgOffset.apply(Math, this); | |
}; | |
Array.prototype.gAvg = function() { | |
return Math.gAvg.apply(Math, this); | |
}; | |
Array.prototype.hAvg = function() { | |
return Math.hAvg.apply(Math, this); | |
}; | |
Array.prototype.med = function() { | |
return Math.med.apply(Math, this); | |
}; | |
Array.prototype.min = function() { | |
return Math.min.apply(Math, this); | |
}; | |
Array.prototype.max = function() { | |
return Math.max.apply(Math, this); | |
}; | |
Array.prototype.sum = function(index) { | |
return Math.sum(this, index); | |
}; | |
Array.prototype.fromDMS = function() { | |
return this[0] + | |
this[1] / 60 + | |
this[2] / 6000; | |
}; | |
// Function prototype | |
Function.prototype.d = function(diffClass) { | |
if((diffClass !== undefined && | |
(!isNumber(diffClass) || | |
(diffClass <= 0)))) return NaN; | |
if(diffClass === undefined) | |
diffClass = 1; | |
var f = this; | |
return function(x, prec) { | |
return Math.diff(f, x, diffClass, prec); | |
}; | |
}; | |
Function.prototype.diff = function(x, diffClass, prec) { | |
return Math.diff(this, x, diffClass, prec); | |
}; | |
Function.prototype.lim = function(x, prec) { | |
return Math.lim(this, x, prec); | |
}; | |
Function.prototype.tanLine = function(x, prec) { | |
if(x === undefined || | |
!isNumber(x) || | |
x === Infinity || | |
x === -Infinity || | |
(prec !== undefined && | |
(!isNumber(prec) || | |
(prec <= 0)))) return NaN; | |
if(prec === undefined) | |
prec = 1; | |
var y = this(x), | |
k = this.diff(x, 1, prec), | |
q = y - k * x; | |
return function(x) { | |
return k * x + q; | |
}; | |
}; | |
Function.prototype.integrate = function(a, b, prec, scale) { | |
return Math.integrate(this, a, b, prec, scale); | |
}; | |
Function.prototype.integRot = function(a, b, prec, scale) { | |
return Math.integRot(this, a, b, prec, scale); | |
}; | |
})(this.NaN, this.Array, this.Math, this.Number); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment