The Math module fills in some gaps in the standard Math library.
Corrects floating point errors
UsefulJS.Math.fcorrect(n[, precision])
n
Numberprecision
NumberReturns: Number The input, possibly corrected for floating point error. If the
input is not a finite number, the return will be the result of converting the input to a
number, Number.NaN
in most cases.
Tiny, uncorrected floating point errors can throw up surprising results:
// What's the base 10 logarithm of 1 billion? Math.log(1e9) / Math.LN10 // 8.999999999999998; almost // What's the tangent of 45 degrees? Math.tan(Math.PI / 4) // 0.9999999999999999; so close // What's the sum of 0.1 and 0.2 0.1 + 0.2 // 0.30000000000000004; really?
fcorrect
calculates the relative error of its input compared to the result
of rounding it to the specified precision. If this value is < the epsilon value of
the system, it assumes that the input has an error and returns the rounded value:
var cFn = UsefulJS.Math.fcorrect; cFn(Math.log(1e9) / Math.LN10) // 9 cFn(Math.tan(Math.PI / 4)) // 1 cFn(0.1 + 0.2, 1) // 0.3; note the precision value
You don't have to wrap all your calculations in fcorrect
, but if you see
some silly results in your output, this method may make them sensible.
Calculates logarithms to any base, not just Math.E
.
UsefulJS.Math.logn(n, base)
n
Numberbase
NumberReturns: Number The logarithm to the specified base.
Throws: RangeError when base is < 0 or not finite.
Silly inputs tend to produce silly results. If n
is 0, the result will generally
be negative infinity. If base
is 1 the result will generally be positive infinity.
If n
is < 0, the result is NaN.
Converts an angle in radians to degrees
UsefulJS.Math.deg(theta)
theta
NumberReturns Number A value in degrees (may be fractional)
Throws: TypeError when theta
is not a finite value.
The Math trigonometric functions work in radians; humans tend to think in terms of degrees. Conversion between the two is straightforward but tedious. Given the growing popularity of game programming, one wonders why angle conversion is not part of the standard library.
UsefulJS.Math.deg(Math.PI / 4); // 45
Converts an angle in radians to degrees, minutes and seconds
UsefulJS.Math.dms(theta)
theta
NumberReturns Array A triplet: degrees, minutes, seconds
Throws: TypeError when theta
is not a finite value.
UsefulJS.Math.dms(1); // [57,17,44.80624709636322]
Converts an angle in degrees (and possibly minutes and seconds) to radians.
UsefulJS.Math.rad(degrees[, minutes, seconds])
degrees
Numberminutes
Numberseconds
NumberReturns Number A value in radians
Throws: TypeError when one or more of the arguments are not finite.
rad
may take one, two or three arguments.
UsefulJS.Math.fcorrect(UsefulJS.Math.rad(57, 17, 44.8062470964)); // 1 // Construct a lookup table of sines from 0 to 360 degrees var sines = (new Array(361)).join('-').split('-').map(function(item, i) { return Math.sin(UsefulJS.Math.rad(i)); });
The fixes for the UsefulJS.Math module are defined in the _math namespace of the input and
output properties of the fix
call. All are applied by default. The property names
are the method names: "sinh", "hypot", "expm1", etc.
expm1
function to calculate ex - 1 (or a dedicated
log1p
function to calculate log(x + 1)), the reason is avoidance
of catastrophic loss of precision for small values of x. For small values of x,
ex and 1 + x are very close to 1. Because of the nature of the floating
point representation of numbers, values closer to 1 than the epsilon value are
indistinguishable from 1 while values closer to 0 than the epsilon value remain
distinguishable from 0. Math.expm1(1e-16)
and Math.log1p(1e-16)
should both return 10-16 while Math.exp(1e-16) - 1
and
Math.log(1 + 1e-16)
will both return 0, a 100% loss of accuracy.Math.acosh(v)
Calculates the hyperbolic area cosine of v
.
See the the MDN documentation for details
Math.asinh(v)
Calculates the hyperbolic area sine of v
.
See the the MDN documentation for details
Math.atanh(v)
Calculates the hyperbolic area tangent of v
.
See the the MDN documentation for details
Math.cbrt(v)
Calculates the cube root of v
.
See the the MDN documentation for details
Math.clz32(v)
Counts the number of leading 0-bits in the 32-bit unsigned int representation of v
.
See the the MDN documentation for details
Math.cosh(v)
Calculates the hyperbolic cosine of v
.
See the the MDN documentation for details
Math.expm1(v)
Calculates the value of ev
- 1.
See the the MDN documentation for details
Math.hypot(a[, b[, c ... ]])
Performs Pythagorean addition on its arguments (i.e. Math.sqrt(a * a + b * b)
)
while avoiding overflow in the intermediate products.
See the the MDN documentation for details
Math.imul(a, b)
Calculates the 32-bit signed integer product of a
and b
.
See the the MDN documentation for details
Math.log1p(v)
Calculates the natural logarithm of v
+ 1.
See the the MDN documentation for details
Math.log10(v)
Calculates the base-10 logarithm of v
.
See the the MDN documentation for details
Math.log2(v)
Calculates the base-2 logarithm of v
.
See the the MDN documentation for details
Math.sign(v)
Calculates the sign of v
.
See the the MDN documentation for details
Math.sinh(v)
Calculates the hyperbolic sine of v
.
See the the MDN documentation for details
Math.tanh(v)
Calculates the hyperbolic tangent of v
.
See the the MDN documentation for details
Math.trunc(v)
Removes the fractional part of v
, rounding towards 0.
See the the MDN documentation for details