Development JavaScript DHTML





    
        jsPro - Math
        
        
/**
 * +-------------------------------------------------------------------------+
 * | jsPro - Error                                                           |
 * +-------------------------------------------------------------------------+
 * | Copyright (C) 2001-2003 Stuart Wigley                                   |
 * +-------------------------------------------------------------------------+
 * | This library is free software; you can redistribute it and/or modify it |
 * | under the terms of the GNU Lesser General Public License as published by|
 * | the Free Software Foundation; either version 2.1 of the License, or (at |
 * | your option) any later version.                                         |
 * |                                                                         |
 * | This library is distributed in the hope that it will be useful, but     |
 * | WITHOUT ANY WARRANTY; without even the implied warranty of              |
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
 * | General Public License for more details.                                |
 * |                                                                         |
 * | You should have received a copy of the GNU Lesser General Public License|
 * | along with this library; if not, write to the Free Software Foundation, |
 * | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
 * +-------------------------------------------------------------------------+
 * | Authors:   Stuart Wigley                      |
 * |            Randolph Fielding                   |
 * +-------------------------------------------------------------------------+
 * $Id: error.js,v 1.15 2003/09/22 04:41:10 gator4life Exp $
 */
/**
 * Property used in Error.handleError to specify how errors are
 * reported. Permissable values are:
 *
 * 0    No errors are reported.
 * 1    Report the error name and error message using the status bar of the
 *      active browser window.
 * 2    Report the error name and error message using an alert box.
 * 3    Report the error name, error message and debug message using an alert
 *      box.
 * 4    Report the error name, error message and debug message using a debug
 *      window. An instance of the Debug() class must be available.
 */
Error.prototype.debugLevel = 4;
/**
 * Uses Error.debugLevel to control how errors are reported. If
 * Error.debugLevel is set to 4, you must substitute the name of
 * your Debug() instance for oDebug in the line
 * var jsProDebugWindow = oDebug.
 *
 * @summary             handles thrown exceptions
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 09/03/03
 * @interface           Error.handleError()
 * @requires            Debug.print(vMixedValue, sMessageType)
 * @see                 Debug()
 * @see                 Debug.print()
 */
Error.prototype.handleError = function() {
    var sDebugMessage = this.debug;
    var sErrorMessage = (sDebugMessage) ? sDebugMessage : '';
    switch (this.debugLevel) {
        case 0 :
            break;
        case 1 :
            window.status = this.name + ': ' + this.message;
            break;
        case 2 :
            window.alert(this.name + '\n\n' + this.message);
            break;
        case 3 :
            window.alert(this.name + '\n\n' + this.message + '\n\n' + sErrorMessage);
            break;
        case 4 :
            var jsProDebugWindow = oDebug;
            if (jsProDebugWindow) {
                var oDebugWindow = jsProDebugWindow.debugWindow;
                if (oDebugWindow && !oDebugWindow.closed) {
                    jsProDebugWindow.print(this.name + ' ' + this.message + ' ' + sErrorMessage, 1);
                }
            }
    }
}
/**
 * Creates an object that is a subclass of Error for handling
 * ArrayIndexOutOfBounds exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 06/27/03
 * @interface           new ArrayIndexOutOfBoundsException(sMethodName,
 *                      iIndex, iArrayLength)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param iIndex        the index of a hypothetical array member attempting to
 *                      be accessed
 * @param iArrayLength  the length of the array
 */
function ArrayIndexOutOfBoundsException(sMethodName, iIndex, iArrayLength) {
    this.name = 'ArrayIndexOutOfBoundsException';
    this.message = sMethodName + ' has been accessed with an illegal index that is either negative or greater than the size of the array.';
    this.debug = 'Attempting to access index ' + iIndex.toString() + ', but array has an index range of 0 to ' + (iArrayLength - 1).toString() + '.';
}
ArrayIndexOutOfBoundsException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling IllegalArgument
 * exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 07/24/03
 * @interface           new IllegalArgumentException(sMethodName,
 *                      vExpectedArgs, iActualArgs)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param vExpectedArgs the number of arguments expected
 * @param iActualArgs   the number of arguments received
 */
function IllegalArgumentException(sMethodName, vExpectedArgs, iActualArgs) {
    this.name = 'IllegalArgumentException';
    this.message = sMethodName + ' has been passed an illegal number of arguments.';
    this.debug = 'Expected ' + vExpectedArgs.toString() + ' argument(s), but received ' + iActualArgs.toString() + ' argument(s).';
}
IllegalArgumentException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling IllegalValue
 * exceptions.
 *
 * @author              Randolph Fielding
 * @version             1.0, 09/22/03
 * @interface           new IllegalValueException(sMethodName,
 *                      sVariableName, vExpectedVal, vActualVal)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param sVariableName the name of the variable containing the illegal value
 * @param vExpectedVal  the value expected in the variable containing the
 *                      illegal value
 * @param vActualVal    the value currently in the variable containing the
 *                      illegal value
 */
function IllegalValueException(sMethodName, sVariableName, vExpectedVal, vActualVal) {
    this.name = 'IllegalValueException';
    this.message = sMethodName + ' has encountered an illegal value in variable ' + sVariableName + '.'
    this.debug = 'Expected a value of ' + vExpectedVal.toString() + ', but contains a value of ' + vActualVal.toString() + '.'
}
IllegalValueException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling
 * MethodNotAvailable exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 06/27/03
 * @interface           new MethodNotAvailableException(sMethodName,
 *                      sMethodNameNA)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param sMethodNameNA the name of the method that was not available
 */
function MethodNotAvailableException(sMethodName, sMethodNameNA) {
    this.name = 'MethodNotAvailableException';
    this.message = 'A method has been called that is not available.';
    this.debug = sMethodName + ' attempted to call ' + sMethodNameNA + '.';
}
MethodNotAvailableException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling
 * PropertyNotAvailable exceptions.
 *
 * @author              Randolph Fielding
 * @version             1.1, 08/01/03
 * @interface           new PropertyNotAvailableException(sMethodName,
 *                      sPropNameNA)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param sPropNameNA   the name of the property that was not available
 */
function PropertyNotAvailableException(sMethodName, sPropNameNA) {
    this.name = 'PropertyNotAvailableException';
    this.message = 'A property has been accessed that is not available.';
    this.debug = sMethodName + ' attempted to access ' + sPropNameNA + '.';
}
PropertyNotAvailableException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling TypeMismatch
 * exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 07/24/03
 * @interface           new TypeMismatchException(sMethodName,
 *                      sExpectedType, sActualType)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param sExpectedType the name of the expected type of an argument
 * @param sActualType   the name of the actual type of an argument
 */
function TypeMismatchException(sMethodName, sExpectedType, sActualType) {
    this.name = 'TypeMismatchException';
    this.message = sMethodName + ' has been passed an argument with an illegal or inappropriate type.';
    this.debug = 'Expected an argument with a type of ' + sExpectedType + ', but received an argument with a type of ' + sActualType + '.';
}
TypeMismatchException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling Unknown
 * exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 06/27/03
 * @interface           new UnknownException(sMethodName)
 * @param sMethodName   the name of the method where the exception was thrown
 */
function UnknownException(sMethodName) {
    this.name = 'UnknownException';
    this.message = 'An unknown error has occurred in ' + sMethodName + '.';
}
UnknownException.prototype = new Error();
        
        
        
/**
 * +-------------------------------------------------------------------------+
 * | jsPro - Debug                                                           |
 * +-------------------------------------------------------------------------+
 * | Copyright (C) 2001-2003 Stuart Wigley                                   |
 * +-------------------------------------------------------------------------+
 * | This library is free software; you can redistribute it and/or modify it |
 * | under the terms of the GNU Lesser General Public License as published by|
 * | the Free Software Foundation; either version 2.1 of the License, or (at |
 * | your option) any later version.                                         |
 * |                                                                         |
 * | This library is distributed in the hope that it will be useful, but     |
 * | WITHOUT ANY WARRANTY; without even the implied warranty of              |
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
 * | General Public License for more details.                                |
 * |                                                                         |
 * | You should have received a copy of the GNU Lesser General Public License|
 * | along with this library; if not, write to the Free Software Foundation, |
 * | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
 * +-------------------------------------------------------------------------+
 * | Authors:   Stuart Wigley                      |
 * |            Randolph Fielding                   |
 * +-------------------------------------------------------------------------+
 * $Id: debug.js,v 1.6 2003/09/22 05:07:41 gator4life Exp $
 */
/**
 * Creates an object that opens a window for debugging.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 09/05/03
 * @interface           new Debug()
 */
function Debug() {
    this.debugWindow = window.open('../debug/debug.html', 'debug', 'width=400,height=600,resizable=yes,scrollbars=yes');
}
/**
 * Clears the contents of the debug window.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 09/05/03
 * @interface           Debug.clear()
 * @return              true if no exceptions are encountered
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              UnknownException
 */
Debug.prototype.clear = function() {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 0) {
            throw vError = new IllegalArgumentException('Debug.clear', 0, iNumArguments);
        }
        var oMessageContainer = document.getElementById('messageContainer');
        if (!oMessageContainer) {
            throw vError = new UnknownException('Debug.clear');
        }
        while (oMessageContainer.hasChildNodes()) {
            oMessageContainer.removeChild(oMessageContainer.firstChild);
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : true;
    }
}
/**
 * Displays content within the debug window.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 09/05/03
 * @interface           Debug.print(vMixedValue)
 * @interface           Debug.print(vMixedValue, iMessageType)
 * @param vMixedValue   content to be displayed within the debug window
 * @param iMessageType  an integer representing the type of content to display
 *                      within the debug window (information: 0; error: 1)
 *                      (optional)
 * @return              true if no exceptions are encountered
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              IllegalValueException
 * @throws              TypeMismatchException
 * @throws              UnknownException
 */
Debug.prototype.print = function(vMixedValue) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        var iMessageType = 0;
        if ((iNumArguments < 1) || (iNumArguments > 2)) {
            throw vError = new IllegalArgumentException('Debug.print', '1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iMessageType = arguments[1];
        }
        if ((typeof iMessageType != 'number') || (iMessageType.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Debug.print', 'integer', typeof iMessageType);
        }
        if ((iMessageType != 0) && (iMessageType != 1)) {
            throw vError = new IllegalValueException('Debug.print', 'iMessageType', '0 or 1', iMessageType);
        }
        var oDebugWindow = this.debugWindow;
        if (!oDebugWindow || oDebugWindow.closed) {
            throw vError = new UnknownException('Debug.print');
        }
        var oDocument = oDebugWindow.document;
        if (!oDocument) {
            throw vError = new UnknownException('Debug.print');
        }
        var oMessageContainer = oDocument.getElementById('messageContainer');
        if (!oMessageContainer) {
            throw vError = new UnknownException('Debug.print');
        }
        var oTitleRow = oDocument.createElement('tr');
        var oTitleCell = oDocument.createElement('td');
        var oBodyRow = oDocument.createElement('tr');
        var oBodyCell = oDocument.createElement('td');
        if (!oTitleRow || !oTitleCell || !oBodyRow || !oBodyCell) {
            throw vError = new UnknownException('Debug.print');
        }
        var oTitleRowStyle = oTitleRow.style;
        if (oTitleRowStyle) {
            oTitleRowStyle.backgroundColor = '#EEE';
            oTitleRowStyle.fontWeight = 700;
        }
        var sOutputString = vMixedValue.toString();
        var sTitle = 'info';
        var sBody = sOutputString;
        if (iMessageType == 1) {
            sTitle = sOutputString.match(/\w+/);
            sBody = sOutputString.replace(/\w+/, '');
            var oBodyCellStyle = oBodyCell.style;
            if (oBodyCellStyle) {
                oBodyCell.style.backgroundColor = '#FCC';
            }
        }
        oMessageContainer.appendChild(oTitleRow);
        oTitleRow.appendChild(oTitleCell);
        oTitleCell.appendChild(oDocument.createTextNode(sTitle));
        oMessageContainer.appendChild(oBodyRow);
        oBodyRow.appendChild(oBodyCell);
        oBodyCell.appendChild(oDocument.createTextNode(sBody));
        oDebugWindow.focus();
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : true;
    }
}
        
        
        
/**
 * +-------------------------------------------------------------------------+
 * | jsPro - Test                                                            |
 * +-------------------------------------------------------------------------+
 * | Copyright (C) 2001-2003 Stuart Wigley                                   |
 * +-------------------------------------------------------------------------+
 * | This library is free software; you can redistribute it and/or modify it |
 * | under the terms of the GNU Lesser General Public License as published by|
 * | the Free Software Foundation; either version 2.1 of the License, or (at |
 * | your option) any later version.                                         |
 * |                                                                         |
 * | This library is distributed in the hope that it will be useful, but     |
 * | WITHOUT ANY WARRANTY; without even the implied warranty of              |
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
 * | General Public License for more details.                                |
 * |                                                                         |
 * | You should have received a copy of the GNU Lesser General Public License|
 * | along with this library; if not, write to the Free Software Foundation, |
 * | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
 * +-------------------------------------------------------------------------+
 * | Authors:   Stuart Wigley                      |
 * |            Randolph Fielding                   |
 * +-------------------------------------------------------------------------+
 * $Id: test.js,v 1.6 2003/09/15 05:07:09 gator4life Exp $
 */
/**
 * Creates an object that provides methods for testing all jsPro libraries.
 *
 * @author              Stuart Wigley
 * @version             1.0, 07/24/03
 * @interface           new Test()
 */
function Test() { }
/**
 * Evaluates and returns the result of a jsPro method using assumptions about
 * the structure and ids of HTML elements in the jsPro HTML test files.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/20/03
 * @interface           Test.evaluateMethod(oButton, sClass)
 * @param oButton       the HTML input-button element that is clicked
 * @param sClass        the name of the jsPro class instance being tested
 * @return              the result of attempting to evaluate a jsPro method
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Test.prototype.evaluateMethod = function(oButton, sClass) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 2) {
            throw vError = new IllegalArgumentException('Error.evaluateMethod', 2, iNumArguments);
        }
        if (typeof oButton != 'object') {
            throw vError = new TypeMismatchException('Error.evaluateMethod', 'object', typeof oButton);
        }
        if (typeof sClass != 'string') {
            throw vError = new TypeMismatchException('Error.evaluateMethod', 'string', typeof sClass);
        }
        var sMethodName = oButton.id;
        var oInput1 = document.getElementById(sMethodName + '1');
        var oInput2 = document.getElementById(sMethodName + '2');
        var oInput3 = document.getElementById(sMethodName + '3');
        var oOutput = document.getElementById(sMethodName + 'Result');
        var sArguments = '';
        if (oInput1) {
            var sInput1Value = oInput1.value;
            if (sInput1Value != '') {
                var fInput1Value = parseFloat(sInput1Value);
                sArguments += (isNaN(fInput1Value)) ? '\'' + sInput1Value + '\'' : fInput1Value;
            }
        }
        if (oInput2) {
            var sInput2Value = oInput2.value;
            if (sInput2Value != '') {
                var fInput2Value = parseFloat(sInput2Value);
                sArguments += (isNaN(fInput2Value)) ? ', \'' + sInput2Value + '\'' : ', ' + fInput2Value;
            }
        }
        if (oInput3) {
            var sInput3Value = oInput3.value;
            if (sInput3Value != '') {
                var fInput3Value = parseFloat(sInput3Value);
                sArguments += (isNaN(fInput3Value)) ? ', \'' + sInput3Value + '\'' : ', ' + fInput3Value;
            }
        }
        var vResult = eval(sClass + '.' + sMethodName + '(' + sArguments + ')');
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        if (oOutput) {
            oOutput.value = vResult;
        }
    }
}
        
        
        
        
/**
 * +-------------------------------------------------------------------------+
 * | jsPro - Math                                                            |
 * +-------------------------------------------------------------------------+
 * | Copyright (C) 2001-2003 Stuart Wigley                                   |
 * +-------------------------------------------------------------------------+
 * | This library is free software; you can redistribute it and/or modify it |
 * | under the terms of the GNU Lesser General Public License as published by|
 * | the Free Software Foundation; either version 2.1 of the License, or (at |
 * | your option) any later version.                                         |
 * |                                                                         |
 * | This library is distributed in the hope that it will be useful, but     |
 * | WITHOUT ANY WARRANTY; without even the implied warranty of              |
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
 * | General Public License for more details.                                |
 * |                                                                         |
 * | You should have received a copy of the GNU Lesser General Public License|
 * | along with this library; if not, write to the Free Software Foundation, |
 * | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
 * +-------------------------------------------------------------------------+
 * | Authors:   Stuart Wigley                      |
 * |            Randolph Fielding                   |
 * +-------------------------------------------------------------------------+
 * $Id: math.js,v 1.24 2003/09/24 13:10:23 wigleys Exp $
 */
/**
 * Calculates and returns the inverse hyperbolic cosine of a number in 2D
 * Cartesian space.
 *
 * @summary             inverse hyperbolic cosine
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.acosh(fX)
 * @param fX            a floating-point number greater than or equal to 1
 * @return              the inverse hyperbolic cosine of fX
 * @return              NaN if fX < 1
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.acosh = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.acosh', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.acosh', 'number', typeof fX);
        }
        var fInvHypCosine = Math.log(fX + Math.sqrt(Math.pow(fX, 2) - 1));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fInvHypCosine;
    }
}
/**
 * Calculates and returns the inverse cotangent of a number in 2D Cartesian
 * space.
 *
 * @summary             inverse cotangent
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.acot(fX)
 * @param fX            a floating-point number
 * @return              the inverse cotangent of fX in radians
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.acot = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.acot', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.acot', 'number', typeof fX);
        }
        var fInvCotangent = Math.atan(1 / fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fInvCotangent;
    }
}
/**
 * Calculates and returns the inverse hyperbolic cotangent of a number in 2D
 * Cartesian space.
 *
 * @summary             inverse hyperbolic cotangent
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.acoth(fX)
 * @param fX            a floating-point number less than or equal to -1 or
 *                      greater than or equal to 1
 * @return              the inverse hyperbolic cotangent of fX
 * @return              NaN if -1 < fX < 1
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.acoth = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.acoth', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.acoth', 'number', typeof fX);
        }
        var fInvHypCotangent = Math.log((fX + 1) / (fX - 1)) / 2;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fInvHypCotangent;
    }
}
/**
 * Calculates and returns the inverse cosecant of a number in 2D Cartesian
 * space.
 *
 * @summary             inverse cosecant
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.acsc(fX)
 * @param fX            a floating-point number less than or equal to -1 or
 *                      greater than or equal to 1
 * @return              the inverse cosecant of fX in radians
 * @return              NaN if -1 < fX < 1
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.acsc = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.acsc', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.acsc', 'number', typeof fX);
        }
        var fInvCosecant = Math.asin(1 / fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fInvCosecant;
    }
}
/**
 * Calculates and returns the inverse hyperbolic cosecant of a number in 2D
 * Cartesian space.
 *
 * @summary             inverse hyperbolic cosecant
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.acsch(fX)
 * @param fX            a floating-point number
 * @return              the inverse hyperbolic cosecant of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.acsch = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.acsch', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.acsch', 'number', typeof fX);
        }
        var fInvHypCosecant = Math.log(Math.sqrt((1 / Math.pow(fX, 2)) + 1) + (1 / fX));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fInvHypCosecant;
    }
}
/**
 * Calculates if two numbers are approximately equal. Approximation defaults
 * to +/- 0.01 but can be optionally set using the fEpsilon
 * argument
 *
 * @summary             approximately equal
 * @author              Stuart Wigley
 * @version             1.0, 09/24/03
 * @interface           Math.approx(fX, fY)
 * @interface           Math.approx(fX, fY, fEpsilon)
 * @param fX            a floating-point number
 * @param fY            a floating-point number
 * @param fEpsilon      accuracy of approximation (optional)
 * @return              true if fX and fY are
 *                      approximately equal; false otherwise
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.approx = function() {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        var fX, fY;
        var fEpsilon = 0.01;
        if (iNumArguments == 2) {
            fX = arguments[0];
            fY = arguments[1];
        } else if (iNumArguments == 3) {
            fX = arguments[0];
            fY = arguments[1];
            fEpsilon = arguments[2];
        } else {
            throw vError = new IllegalArgumentException('Math.approx', '2 or 3', iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.approx', 'number', typeof fX);
        }
        if (typeof fY != 'number') {
            throw vError = new TypeMismatchException('Math.approx', 'number', typeof fY);
        }
        if (typeof fEpsilon != 'number') {
            throw vError = new TypeMismatchException('Math.approx', 'number', typeof fEpsilon);
        }
        var bApprox = (Math.abs(fX - fY) < fEpsilon) ? true : false;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : bApprox;
    }
}
/**
 * Calculates the polar angle (argument) of a pair of rectangular coordinates.
 *
 * @summary             polar angle (argument)
 * @author              Stuart Wigley
 * @version             1.0, 09/24/03
 * @interface           Math.arg(fX, fY)
 * @requires            math.sign()
 * @param fX            a floating-point number
 * @param fY            a floating-point number
 * @return              the polar angle (argument)
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 * @throws              MethodNotAvailableException
 * @see                 math.sign()
 */
Math.arg = function(fX, fY) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (!('sign' in this)) {
            throw vError = new MethodNotAvailableException('Math.arg', 'Math.sign');
        }
        if (iNumArguments != 2) {
            throw vError = new IllegalArgumentException('Math.arg', 2, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.arg', 'number', typeof fX);
        }
        if (typeof fY != 'number') {
            throw vError = new TypeMismatchException('Math.arg', 'number', typeof fY);
        }
        var fArgument = Math.atan2(fY, fX) + (Math.PI / 2) * Math.sign(fY) * (1 - Math.sign(fX));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fArgument;
    }
}
/**
 * Calculates and returns the inverse secant of a number in 2D Cartesian
 * space.
 *
 * @summary             inverse secant
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.asec(fX)
 * @param fX            a floating-point number less than or equal to -1 or
 *                      greater than or equal to 1
 * @return              the inverse secant of fX in radians
 * @return              NaN if -1 < fX < 1
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.asec = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.asec', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.asec', 'number', typeof fX);
        }
        var fInvSecant = Math.acos(1 / fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fInvSecant;
    }
}
/**
 * Calculates and returns the inverse hyperbolic secant of a number in 2D
 * Cartesian space.
 *
 * @summary             inverse hyperbolic secant
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.asech(fX)
 * @param fX            a floating-point number between 0 and 1 inclusive
 * @return              the inverse hyperbolic secant of fX
 * @return              NaN if fX < 0 or
 *                      fX > 1
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.asech = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.asech', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.asech', 'number', typeof fX);
        }
        var fInvHypSecant = Math.log(Math.sqrt((1 / Math.pow(fX, 2)) - 1) + (1 / fX));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fInvHypSecant;
    }
}
/**
 * Calculates and returns the inverse hyperbolic sine of a number in 2D
 * Cartesian space.
 *
 * @summary             inverse hyperbolic sine
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.asinh(fX)
 * @param fX            a floating-point number
 * @return              the inverse hyperbolic sine of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.asinh = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.asinh', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.asinh', 'number', typeof fX);
        }
        var fInvHypSine = Math.log(fX + Math.sqrt(Math.pow(fX, 2) + 1));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fInvHypSine;
    }
}
/**
 * Calculates and returns the inverse hyperbolic tangent of a number in 2D
 * Cartesian space.
 *
 * @summary             inverse hyperbolic tangent
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.atanh(fX)
 * @param fX            a floating-point number between -1 and 1 inclusive
 * @return              the inverse hyperbolic tangent of fX
 * @return              NaN if fX < -1 or
 *                      fX > 1
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.atanh = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.atanh', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.atanh', 'number', typeof fX);
        }
        var fInvHypTangent = Math.log((1 + fX) / (1 - fX)) / 2;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fInvHypTangent;
    }
}
/**
 * Converts a number from one base to another base.
 *
 * @summary             convert base
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 09/03/03
 * @interface           Math.baseConvert(vNumber, iBaseFrom,
 *                      iBaseTo)

 * @param vNumber       an integer, a floating-point number, or a string to
 *                      convert from one base to another base
 * @param iBaseFrom     the base to convert from as an integer between 2 and
 *                      36
 * @param iBaseTo       the base to convert to as an integer between 2 and 36
 * @return              a string representation of the converted number
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              IllegalValueException
 * @throws              TypeMismatchException
 */
Math.baseConvert = function(vNumber, iBaseFrom, iBaseTo) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 3) {
            throw vError = new IllegalArgumentException('Math.baseConvert', 3, iNumArguments);
        }
        if ((typeof vNumber != 'number') && (typeof vNumber != 'string')) {
            throw vError = new TypeMismatchException('Math.baseCovert', 'number or string', typeof vNumber);
        }
        if ((typeof iBaseFrom != 'number') || (iBaseFrom.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.baseConvert', 'integer', typeof iBaseFrom);
        }
        if ((iBaseFrom < 2) || (iBaseFrom > 36)) {
            throw vError = new IllegalValueException('Math.baseConvert', 'iBaseFrom', '2, 3, 4, ..., 35 or 36', iBaseFrom);
        }
        if ((typeof iBaseTo != 'number') || (iBaseTo.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.baseConvert', 'integer', typeof iBaseTo);
        }
        if ((iBaseTo < 2) || (iBaseTo > 36)) {
            throw vError = new IllegalValueException('Math.baseConvert', 'iBaseTo', '2, 3, 4, ..., 35 or 36', iBaseTo);
        }
        var sConvertedNum = parseInt(vNumber.toString(), iBaseFrom).toString(iBaseTo);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sConvertedNum;
    }
}
/**
 * Converts a binary number into its decimal equivalent.
 *
 * @summary             binary to decimal conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.3, 08/08/03
 * @interface           Math.bin2dec(lBinaryNum)
 * @param lBinaryNum    a binary number
 * @return              the decimal equivalent of lBinaryNum
 * @return              NaN if lBinaryNum is not a
 *                      binary number
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.bin2dec = function(lBinaryNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.bin2dec', 1, iNumArguments);
        }
        if ((typeof lBinaryNum != 'number') || (lBinaryNum.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.bin2dec', 'long', typeof lBinaryNum);
        }
        var iDecimalNum = parseInt(lBinaryNum.toString(), 2);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : iDecimalNum;
    }
}
/**
 * Converts a binary number into its hexadecimal equivalent.
 *
 * @summary             binary to hexadecimal conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.bin2hex(lBinaryNum)
 * @param lBinaryNum    a binary number
 * @return              the hexadecimal equivalent of lBinaryNum
 * @return              NaN if lBinaryNum is not a
 *                      binary number
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.bin2hex = function(lBinaryNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.bin2hex', 1, iNumArguments);
        }
        if ((typeof lBinaryNum != 'number') || (lBinaryNum.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.bin2hex', 'long', typeof lBinaryNum);
        }
        var sHexadecimalNum = parseInt(lBinaryNum.toString(), 2).toString(16);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sHexadecimalNum;
    }
}
/**
 * Converts a binary number into its octal equivalent.
 *
 * @summary             binary to octal conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.bin2oct(lBinaryNum)
 * @param lBinaryNum    a binary number
 * @return              the octal equivalent of lBinaryNum
 * @return              NaN if lBinaryNum is not a
 *                      binary number
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.bin2oct = function(lBinaryNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.bin2oct', 1, iNumArguments);
        }
        if ((typeof lBinaryNum != 'number') || (lBinaryNum.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.bin2oct', 'long', typeof lBinaryNum);
        }
        var sOctalNum = parseInt(lBinaryNum.toString(), 2).toString(8);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sOctalNum;
    }
}
/**
 * Calculates and returns the hyperbolic cosine of a number in 2D Cartesian
 * space.
 *
 * @summary             hyperbolic cosine
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.cosh(fX)
 * @param fX            a floating-point number
 * @return              the hyperbolic cosine of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.cosh = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.cosh', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.cosh', 'number', typeof fX);
        }
        var fHypCosine = (Math.exp(fX) + Math.exp(-fX)) / 2;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fHypCosine;
    }
}
/**
 * Calculates and returns the cotangent of a number in 2D Cartesian space.
 *
 * @summary             cotangent
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.cot(fX)
 * @param fX            a floating-point number
 * @return              the cotangent of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.cot = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.cot', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.cot', 'number', typeof fX);
        }
        var fCotangent = 1 / Math.tan(fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fCotangent;
    }
}
/**
 * Calculates and returns the hyperbolic cotangent of a number in 2D Cartesian
 * space.
 *
 * @summary             hyperbolic cotangent
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.coth(fX)
 * @param fX            a floating-point number
 * @return              the hyperbolic cotangent of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.coth = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.coth', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.coth', 'number', typeof fX);
        }
        var fHypCotangent = (Math.exp(fX) + Math.exp(-fX)) / (Math.exp(fX) - Math.exp(-fX));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fHypCotangent;
    }
}
/**
 * Calculates and returns the coversine of a number in 2D Cartesian space.
 *
 * @summary             coversine
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.cov(fX)
 * @param fX            a floating-point number
 * @return              the coversine of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.cov = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.cov', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.cov', 'number', typeof fX);
        }
        var fCoversine = 1 - Math.sin(fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fCoversine;
    }
}
/**
 * Calculates and returns the cosecant of a number in 2D Cartesian space.
 *
 * @summary             cosecant
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.csc(fX)
 * @param fX            a floating-point number
 * @return              the cosecant of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.csc = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.csc', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.csc', 'number', typeof fX);
        }
        var fCosecant = 1 / Math.sin(fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fCosecant;
    }
}
/**
 * Calculates and returns the hyperbolic cosecant of a number in 2D Cartesian
 * space.
 *
 * @summary             hyperbolic cosecant
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.csch(fX)
 * @param fX            a floating-point number
 * @return              the hyperbolic cosecant of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.csch = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.csch', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.csch', 'number', typeof fX);
        }
        var fHypCosecant = 2 / (Math.exp(fX) - Math.exp(-fX));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fHypCosecant;
    }
}
/**
 * Converts a decimal number into its binary equivalent.
 *
 * @summary             decimal to binary conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.dec2bin(lDecimalNum)
 * @param lDecimalNum   a long integer
 * @return              the binary equivalent of lDecimalNum
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.dec2bin = function(lDecimalNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.dec2bin', 1, iNumArguments);
        }
        if ((typeof lDecimalNum != 'number') || (lDecimalNum.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.dec2bin', 'long', typeof lDecimalNum);
        }
        var sBinaryNum = lDecimalNum.toString(2);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sBinaryNum;
    }
}
/**
 * Converts a decimal number into its hexadecimal equivalent.
 *
 * @summary             decimal to hexadecimal conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.3, 08/08/03
 * @interface           Math.dec2hex(lDecimalNum)
 * @param lDecimalNum   a long integer
 * @return              the hexadecimal equivalent of lDecimalNum
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.dec2hex = function(lDecimalNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.dec2hex', 1, iNumArguments);
        }
        if ((typeof lDecimalNum != 'number') || (lDecimalNum.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.dec2hex', 'long', typeof lDecimalNum);
        }
        var sHexadecimalNum = lDecimalNum.toString(16);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sHexadecimalNum;
    }
}
/**
 * Converts a decimal number into its octal equivalent.
 *
 * @summary             decimal to octal conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.dec2oct(lDecimalNum)
 * @param lDecimalNum   a long integer
 * @return              the octal equivalent of lDecimalNum
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.dec2oct = function(lDecimalNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.dec2oct', 1, iNumArguments);
        }
        if ((typeof lDecimalNum != 'number') || (lDecimalNum.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.dec2oct', 'long', typeof lDecimalNum);
        }
        var sOctalNum = lDecimalNum.toString(8);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sOctalNum;
    }
}
/**
 * Converts an angle in degrees into its equivalent in gradians.
 *
 * @summary             degree to gradian conversion
 * @author              Randolph Fielding
 * @author              Stuart Wigley
 * @version             1.1, 08/08/03
 * @interface           Math.deg2grad(fDegrees)
 * @param fDegrees      an angle in degrees
 * @return              the equivalent of fDegrees in gradians
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.deg2grad = function(fDegrees) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.deg2grad', 1, iNumArguments);
        }
        if (typeof fDegrees != 'number') {
            throw vError = new TypeMismatchException('Math.deg2grad', 'number', typeof fDegrees);
        }
        var fGradians = (400 / 360) * fDegrees;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fGradians;
    }
}
/**
 * Converts an angle in degrees into its equivalent in radians.
 *
 * @summary             degree to radian conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.deg2rad(fDegrees)
 * @param fDegrees      an angle in degrees
 * @return              the equivalent of fDegrees in radians
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.deg2rad = function(fDegrees) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.deg2rad', 1, iNumArguments);
        }
        if (typeof fDegrees != 'number') {
            throw vError = new TypeMismatchException('Math.deg2rad', 'number', typeof fDegrees);
        }
        var fRadians = ((2 * Math.PI) / 360) * fDegrees;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fRadians;
    }
}
/**
 * Calculates the exponent of 10. ie 10 to the power of fX
 *
 * @summary             exponent of 10
 * @author              Stuart Wigley
 * @version             1.0, 09/24/03
 * @interface           Math.exp10(fX)
 * @param fX            a floating-point number
 * @return              10 raised to the power of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.exp10 = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.exp10', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.exp10', 'number', typeof fX);
        }
        var fExponent10 = Math.pow(10, fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fExponent10;
    }
}
/**
 * Calculates and returns exp(x) - 1 for a number x.
 *
 * @summary             exp(x) - 1
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.expm1(fX)
 * @param fX            a floating-point number
 * @return              Math.exp(fX) - 1 for fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.expm1 = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.expm1', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.expm1', 'number', typeof fX);
        }
        var fExpm1 = ((fX > -1.0e-6) && (fX < 1.0e-6)) ? fX + (Math.pow(fX, 2) / 2) : Math.exp(fX) - 1;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fExpm1;
    }
}
/**
 * Calculates and returns the exsecant of a number in 2D Cartesian space.
 *
 * @summary             exsecant
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.exsec(fX)
 * @param fX            a floating-point number
 * @return              the exsecant of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.exsec = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.exsec', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.exsec', 'number', typeof fX);
        }
        var fExsecant = (1 / Math.cos(fX)) - 1;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fExsecant;
    }
}
/**
 * Calculates and returns the xth term of the Fibonacci sequence.
 *
 * @summary             Fibonacci sequence
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.fibonacci(iX)
 * @param iX            an integer
 * @return              the Fibonacci number corresponding to the
 *                      iXth term of the Fibonacci sequence
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.fibonacci = function(iX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.fibonacci', 1, iNumArguments);
        }
        if ((typeof iX != 'number') || (iX.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.fibonacci', 'integer', typeof iX);
        }
        var iFibonacciNum = Math.round((Math.pow(1 + Math.sqrt(5), iX) - Math.pow(1 - Math.sqrt(5), iX)) / (Math.pow(2, iX) * Math.sqrt(5)));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : iFibonacciNum;
    }
}
/**
 * Calculates and returns the floating-point remainder of one number divided
 * by another number.
 *
 * @summary             floating-point remainder
 * @author              Stuart Wigley
 * @version             1.0, 09/03/03
 * @interface           Math.fmod(fDividend, fDivisor)
 * @param fDividend     a floating-point number
 * @param fDivisor      a floating-point number
 * @return              the floating-point remainder of fDividend
 *                      divided by fDivisor
 * @return              NaN if fDivisor = 0
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.fmod = function(fDividend, fDivisor) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 2) {
            throw vError = new IllegalArgumentException('Math.fmod', 2, iNumArguments);
        }
        if (typeof fDividend != 'number') {
            throw vError = new TypeMismatchException('Math.fmod', 'number', typeof fDividend);
        }
        if (typeof fDivisor != 'number') {
            throw vError = new TypeMismatchException('Math.fmod', 'number', typeof fDivisor);
        }
        var fRemainder = fDividend - (Math.floor(fDividend / fDivisor) * fDivisor);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fRemainder;
    }
}
/**
 * Calculates and returns the Gudermannian number of a number in 2D Cartesian
 * space using the Gudermannian function.
 *
 * @summary             Gudermannian function
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.gd(fX)
 * @param fX            a floating-point number
 * @return              the Gudermannian number of fX in radians
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.gd = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.gd', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.gd', 'number', typeof fX);
        }
        var fGudermannianNum = (2 * Math.atan(Math.exp(fX))) - (Math.PI / 2);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fGudermannianNum;
    }
}
/**
 * Converts an angle in gradians into its equivalent in degrees.
 *
 * @summary             gradian to degree conversion
 * @author              Randolph Fielding
 * @author              Stuart Wigley
 * @version             1.1, 08/08/03
 * @interface           Math.grad2deg(fGradians)
 * @param fGradians     an angle in gradians
 * @return              the equivalent of fGradians in degrees
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.grad2deg = function(fGradians) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.grad2deg', 1, iNumArguments);
        }
        if (typeof fGradians != 'number') {
            throw vError = new TypeMismatchException('Math.grad2deg', 'number', typeof fGradians);
        }
        var fDegrees = (360 / 400) * fGradians;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fDegrees;
    }
}
/**
 * Converts an angle in gradians into its equivalent in radians.
 *
 * @summary             gradian to radian conversion
 * @author              Randolph Fielding
 * @author              Stuart Wigley
 * @version             1.1, 08/08/03
 * @interface           Math.grad2rad(fGradians)
 * @param fGradians     an angle in gradians
 * @return              the equivalent of fGradians in radians
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.grad2rad = function(fGradians) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.grad2rad', 1, iNumArguments);
        }
        if (typeof fGradians != 'number') {
            throw vError = new TypeMismatchException('Math.grad2rad', 'number', typeof fGradians);
        }
        var fRadians = ((2 * Math.PI) / 400) * fGradians;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fRadians;
    }
}
/**
 * Calculates and returns the haversine of a number in 2D Cartesian space.
 *
 * @summary             haversine
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.hav(fX)
 * @param fX            a floating-point number
 * @return              the haversine of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.hav = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.hav', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.hav', 'number', typeof fX);
        }
        var fHaversine = (1 - Math.cos(fX)) / 2;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fHaversine;
    }
}
/**
 * Converts a hexadecimal number into its binary equivalent.
 *
 * @summary             hexadecimal to binary conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.hex2bin(sHexNum)
 * @param sHexNum       the string representation of a hexadecimal number
 * @return              the binary equivalent of sHexNum
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.hex2bin = function(sHexNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.hex2bin', 1, iNumArguments);
        }
        if (typeof sHexNum != 'string') {
            throw vError = new TypeMismatchException('Math.hex2bin', 'string', typeof sHexNum);
        }
        var sBinaryNum = parseInt(sHexNum, 16).toString(2);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sBinaryNum;
    }
}
/**
 * Converts a hexadecimal number into its decimal equivalent.
 *
 * @summary             hexadecimal to decimal conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.hex2dec(sHexNum)
 * @param sHexNum       the string representation of a hexadecimal number
 * @return              the decimal equivalent of sHexNum
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.hex2dec = function(sHexNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.hex2dec', 1, iNumArguments);
        }
        if (typeof sHexNum != 'string') {
            throw vError = new TypeMismatchException('Math.hex2dec', 'string', typeof sHexNum);
        }
        var iDecimalNum = parseInt(sHexNum, 16);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : iDecimalNum;
    }
}
/**
 * Converts a hexadecimal number into its octal equivalent.
 *
 * @summary             hexadecimal to octal conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.hex2oct(sHexNum)
 * @param sHexNum       the string representation of a hexadecimal number
 * @return              the octal equivalent of sHexNum
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.hex2oct = function(sHexNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.hex2oct', 1, iNumArguments);
        }
        if (typeof sHexNum != 'string') {
            throw vError = new TypeMismatchException('Math.hex2oct', 'string', typeof sHexNum);
        }
        var sOctalNum = parseInt(sHexNum, 16).toString(8);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sOctalNum;
    }
}
/**
 * Calculates and returns the length of the hypotenuse of a right triangle
 * (side C) in 2D Cartesian space.
 *
 * @summary             hypotenuse
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.hypot(fLengthA, fLengthB)
 * @param fLengthA      the length of side A of a right triangle
 * @param fLengthB      the length of side B of a right triangle
 * @return              the length of the hypotenuse of the right triangle
 *                      (side C)
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.hypot = function(fLengthA, fLengthB) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 2) {
            throw vError = new IllegalArgumentException('Math.hypot', 2, iNumArguments);
        }
        if (typeof fLengthA != 'number') {
            throw vError = new TypeMismatchException('Math.hypot', 'number', typeof fLengthA);
        }
        if (typeof fLengthB != 'number') {
            throw vError = new TypeMismatchException('Math.hypot', 'number', typeof fLengthB);
        }
        var fHypotenuse = Math.sqrt(Math.pow(fLengthA, 2) + Math.pow(fLengthB, 2));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fHypotenuse;
    }
}
/**
 * Determines if a number is even.
 *
 * @summary             is even?
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.isEven(fX)
 * @param fX            a floating-point number
 * @return              true if fX is even
 * @return              false if fX is odd
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.isEven = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.isEven', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.isEven', 'number', typeof fX);
        }
        var bIsEven = (fX % 2) == 0;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : bIsEven;
    }
}
/**
 * Determines if a number is odd.
 *
 * @summary             is odd?
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.isOdd(fX)
 * @param fX            a floating-point number
 * @return              true if fX is odd
 * @return              false if fX is even
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.isOdd = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.isOdd', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.isOdd', 'number', typeof fX);
        }
        var bIsOdd = (fX % 2) != 0;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : bIsOdd;
    }
}
/**
 * Determines if a number is prime (a positive integer greater than 1 that has
 * no positive integer divisors other than 1 and itself).
 *
 * @summary             is prime?
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 07/04/03
 * @interface           Math.isPrime(iX)
 * @param iX            a positive integer greater than 1
 * @return              true if iX is prime
 * @return              false if iX is not prime
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              IllegalValueException
 * @throws              TypeMismatchException
 */
Math.isPrime = function(iX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.isPrime', 1, iNumArguments);
        }
        if ((typeof iX != 'number') || (iX.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.isPrime', 'integer', typeof iX);
        }
        if (iX < 2) {
            throw vError = new IllegalValueException('Math.isPrime', 'iX', '2 or greater', iX);
        }
        var bIsPrime = true;
        if ((iX != 2) && ((iX % 2) == 0)) {
            bIsPrime = false;
        } else {
            for (var i = 3; i <= Math.sqrt(iX); i += 2) {
                if ((iX % i) == 0) {
                    bIsPrime = false;
                }
            }
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : bIsPrime;
    }
}
/**
 * Calculates and returns the base-10 logarithm of a number.
 *
 * @summary             base-10 logarithm
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.log10(fX)
 * @param fX            a floating-point number greater than or equal to 0
 * @return              the base-10 logarithm of fX
 * @return              NaN if fX < 0
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.log10 = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.log10', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.log10', 'number', typeof fX);
        }
        var fBase10Log = Math.LOG10E * Math.log(fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fBase10Log;
    }
}
/**
 * Calculates and returns the base-2 logarithm of a number.
 *
 * @summary             base-2 logarithm
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.log2(fX)
 * @param fX            a floating-point number greater than or equal to 0
 * @return              the base-2 logarithm of fX
 * @return              NaN if fX < 0
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.log2 = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.log2', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.log2', 'number', typeof fX);
        }
        var fBase2Log = Math.LOG2E * Math.log(fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fBase2Log;
    }
}
/**
 * Calculates and returns log(1 + x) for a number x.
 *
 * @summary             log(1 + x)
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.log1p(fX)
 * @param fX            a floating-point number greater than or equal to -1
 * @return              Math.log(1 + fX) for fX
 * @return              NaN if fX < -1
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.log1p = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.log1p', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.log1p', 'number', typeof fX);
        }
        var fLog1p = ((fX > -1.0e-8) && (fX < 1.0e-8)) ? fX - (Math.pow(fX, 2) / 2) : Math.log(1 + fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fLog1p;
    }
}
/**
 * Determines if a number is valid according to the LUHN formula.
 *
 * @summary             LUHN formula
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.luhn(lX)
 * @param lX            a long integer greater than or equal to 10
 * @return              true if lX is valid
 * @return              false if lX is invalid
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              IllegalValueException
 * @throws              TypeMismatchException
 */
Math.luhn = function(lX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.luhn', 1, iNumArguments);
        }
        if ((typeof lX != 'number') || (lX.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.luhn', 'long', typeof lX);
        }
        if (lX < 10) {
            throw vError = new IllegalValueException('Math.luhn', 'lX', '10 or greater', lX);
        }
        var sX = lX.toString();
        var iModifiedXlength = sX.length - 1;
        var bDouble = false;
        var iSum = 0;
        for (var i = iModifiedXlength; i >= 0; i--) {
            var iTempNum = parseInt(sX.charAt(i));
            if (bDouble) {
                iTempNum *= 2;
                if (iTempNum > 9) {
                    iTempNum -= 9;
                }
            }
            iSum += iTempNum;
            bDouble = !bDouble;
        }
        var bIsValidLuhn = (iSum % 10) == 0;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : bIsValidLuhn;
    }
}
/**
 * Converts an octal number into its binary equivalent.
 *
 * @summary             octal to binary conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.oct2bin(lOctalNum)
 * @param lOctalNum     a long integer
 * @return              the binary equivalent of lOctalNum
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.oct2bin = function(lOctalNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.oct2bin', 1, iNumArguments);
        }
        if ((typeof lOctalNum != 'number') || (lOctalNum.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.oct2bin', 'long', typeof lOctalNum);
        }
        var sBinaryNum = parseInt(lOctalNum.toString(), 8).toString(2);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sBinaryNum;
    }
}
/**
 * Converts an octal number into its decimal equivalent.
 *
 * @summary             octal to decimal conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.oct2dec(lOctalNum)
 * @param lOctalNum     a long integer
 * @return              the decimal equivalent of lOctalNum
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.oct2dec = function(lOctalNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.oct2dec', 1, iNumArguments);
        }
        if ((typeof lOctalNum != 'number') || (lOctalNum.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.oct2dec', 'long', typeof lOctalNum);
        }
        var iDecimalNum = parseInt(lOctalNum.toString(), 8);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : iDecimalNum;
    }
}
/**
 * Converts an octal number into its hexadecimal equivalent.
 *
 * @summary             octal to hexadecimal conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/08/03
 * @interface           Math.oct2hex(lOctalNum)
 * @param lOctalNum     a long integer
 * @return              the hexadecimal equivalent of lOctalNum
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.oct2hex = function(lOctalNum) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.oct2hex', 1, iNumArguments);
        }
        if ((typeof lOctalNum != 'number') || (lOctalNum.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.oct2hex', 'long', typeof lOctalNum);
        }
        var sHexadecimalNum = parseInt(lOctalNum.toString(), 8).toString(16);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : sHexadecimalNum;
    }
}
/**
 * Calculates pi using one of the four two-term, Machin-like formulas.
 *
 * @summary             calculate pi
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 09/14/03
 * @interface           Math.pi()
 * @interface           Math.pi(iFormula)
 * @param iFormula      an integer representing the two-term, Machin-like
 *                      formula to use for calculating pi (Machin's formula: 0;
 *                      Euler's Machin-like formula: 1; Hermann's formula: 2;
 *                      Hutton's formula: 3) (optional)
 * @return              pi
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              IllegalValueException
 * @throws              TypeMismatchException
 */
Math.pi = function() {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        var iFormula = 0;
        if (iNumArguments > 1) {
            throw vError = new IllegalArgumentException('Math.pi', '0 or 1', iNumArguments);
        } else if (iNumArguments == 1) {
            iFormula = arguments[0];
        }
        if ((typeof iFormula != 'number') || (iFormula.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Math.pi', 'integer', typeof iFormula);
        }
        if ((iFormula != 0) && (iFormula != 1) && (iFormula != 2) && (iFormula != 3)) {
            throw vError = new IllegalValueException('Math.pi', 'iFormula', '0, 1, 2 or 3', iFormula);
        }
        switch (iFormula) {
            case 1  : var fPi = 4 * (Math.atan(1 / 2) + Math.atan(1 / 3)); break;
            case 2  : var fPi = 4 * ((2 * Math.atan(1 / 2)) - Math.atan(1 / 7)); break;
            case 3  : var fPi = 4 * ((2 * Math.atan(1 / 3)) + Math.atan(1 / 7)); break;
            case 0  :
            default : var fPi = 4 * ((4 * Math.atan(1 / 5)) - Math.atan(1 / 239)); break;
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fPi;
    }
}
/**
 * Converts an angle in radians into its equivalent in degrees.
 *
 * @summary             radian to degree conversion
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.rad2deg(fRadians)
 * @param fRadians      an angle in radians
 * @return              the equivalent of fRadians in degrees
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.rad2deg = function(fRadians) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.rad2deg', 1, iNumArguments);
        }
        if (typeof fRadians != 'number') {
            throw vError = new TypeMismatchException('Math.rad2deg', 'number', typeof fRadians);
        }
        var fDegrees = (360 / (2 * Math.PI)) * fRadians;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fDegrees;
    }
}
/**
 * Converts an angle in radians into its equivalent in gradians.
 *
 * @summary             radian to gradian conversion
 * @author              Randolph Fielding
 * @author              Stuart Wigley
 * @version             1.2, 08/08/03
 * @interface           Math.rad2grad(fRadians)
 * @param fRadians      an angle in radians
 * @return              the equivalent of fRadians in gradians
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.rad2grad = function(fRadians) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.rad2grad', 1, iNumArguments);
        }
        if (typeof fRadians != 'number') {
            throw vError = new TypeMismatchException('Math.rad2grad', 'number', typeof fRadians);
        }
        var fGradians = (400 / (2 * Math.PI)) * fRadians;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fGradians;
    }
}
/**
 * Calculates and returns the secant of a number in 2D Cartesian space.
 *
 * @summary             secant
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.sec(fX)
 * @param fX            a floating-point number
 * @return              the secant of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.sec = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.sec', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.sec', 'number', typeof fX);
        }
        var fSecant = 1 / Math.cos(fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fSecant;
    }
}
/**
 * Calculates and returns the hyperbolic secant of a number in 2D Cartesian
 * space.
 *
 * @summary             hyperbolic secant
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.sech(fX)
 * @param fX            a floating-point number
 * @return              the hyperbolic secant of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.sech = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.sech', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.sech', 'number', typeof fX);
        }
        var fHypSecant = 2 / (Math.exp(fX) + Math.exp(-fX));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fHypSecant;
    }
}
/**
 * Calculates and returns the sigmoid of a number in 2D Cartesian space using
 * the sigmoid function.
 *
 * @summary             sigmoid function
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.sigmoid(fX)
 * @param fX            a floating-point number
 * @return              the sigmoid of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.sigmoid = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.sigmoid', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.sigmoid', 'number', typeof fX);
        }
        var fSigmoid = 1 / (1 + Math.exp(-fX));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fSigmoid;
    }
}
/**
 * Calculates and returns the sign of a number.
 *
 * @summary             sign
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.sign(fX)
 * @param fX            a floating-point number
 * @return              0 if fX == 0
 * @return              1 if fX is positive
 * @return              -1 if fX is negative
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.sign = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.sign', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.sign', 'number', typeof fX);
        }
        var iSign = (fX == 0) ? 0 : fX / Math.abs(fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : iSign;
    }
}
/**
 * Calculates and returns the sinc of a number in 2D Cartesian space using the
 * sinc function.
 *
 * @summary             sinc function
 * @author              Randolph Fielding
 * @author              Stuart Wigley
 * @version             1.2, 08/08/03
 * @interface           Math.sinc(fX)
 * @param fX            a floating-point number
 * @return              the sinc of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.sinc = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.sinc', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.sinc', 'number', typeof fX);
        }
        var fSinc = (fX == 0) ? 1 : Math.sin(fX) / fX;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fSinc;
    }
}
/**
 * Calculates and returns the hyperbolic sine of a number in 2D Cartesian
 * space.
 *
 * @summary             hyperbolic sine
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.sinh(fX)
 * @param fX            a floating-point number
 * @return              the hyperbolic sine of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.sinh = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.sinh', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.sinh', 'number', typeof fX);
        }
        var fHypSine = (Math.exp(fX) - Math.exp(-fX)) / 2;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fHypSine;
    }
}
/**
 * Calculates and returns the square of a number.
 *
 * @summary             square
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.sq(fX)
 * @param fX            a floating-point number
 * @return              the square of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.sq = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.sq', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.sq', 'number', typeof fX);
        }
        var fSquare = Math.pow(fX, 2);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fSquare;
    }
}
/**
 * Calculates and returns the tanc of a number in 2D Cartesian space using the
 * tanc function.
 *
 * @summary             tanc function
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.tanc(fX)
 * @param fX            a floating-point number
 * @return              the tanc of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.tanc = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.tanc', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.tanc', 'number', typeof fX);
        }
        var fTanc = (fX == 0) ? 1 : Math.tan(fX) / fX;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fTanc;
    }
}
/**
 * Calculates and returns the hyperbolic tangent of a number in 2D Cartesian
 * space.
 *
 * @summary             hyperbolic tangent
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.tanh(fX)
 * @param fX            a floating-point number
 * @return              the hyperbolic tangent of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.tanh = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.tanh', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.tanh', 'number', typeof fX);
        }
        var fHypTangent = (Math.exp(fX) - Math.exp(-fX)) / (Math.exp(fX) + Math.exp(-fX));
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fHypTangent;
    }
}
/**
 * Calculates and returns the versine of a number in 2D Cartesian space.
 *
 * @summary             versine
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Math.vers(fX)
 * @param fX            a floating-point number
 * @return              the versine of fX
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Math.vers = function(fX) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Math.vers', 1, iNumArguments);
        }
        if (typeof fX != 'number') {
            throw vError = new TypeMismatchException('Math.vers', 'number', typeof fX);
        }
        var fVersine = 1 - Math.cos(fX);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fVersine;
    }
}
                
        
            var oDebug = new Debug();
            var oTest = new Test();
        
    
    
        
            
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
            
        
Math.acosh()
Math.acot()
Math.acoth()
Math.acsc()
Math.acsch()
Math.approx()
                        
                        
                        
                    
Math.arg()
                        
                        
                    
Math.asec()
Math.asech()
Math.asinh()
Math.atanh()
Math.baseConvert()
                        
                        
                        
                    
Math.bin2dec()
Math.bin2hex()
Math.bin2oct()
Math.cosh()
Math.cot()
Math.coth()
Math.cov()
Math.csc()
Math.csch()
Math.dec2bin()
Math.dec2hex()
Math.dec2oct()
Math.deg2grad()
Math.deg2rad()
Math.exp10()
Math.expm1()
Math.exsec()
Math.fibonacci()
Math.fmod()
                        
                        
                    
Math.gd()
Math.grad2deg()
Math.grad2rad()
Math.hav()
Math.hex2bin()
Math.hex2dec()
Math.hex2oct()
Math.hypot()
                        
                        
                    
Math.isEven()
Math.isOdd()
Math.isPrime()
Math.log10()
Math.log2()
Math.log1p()
Math.logn()
                        
                        
                    
Math.luhn()
Math.oct2bin()
Math.oct2dec()
Math.oct2hex()
Math.pi()
Math.rad2deg()
Math.rad2grad()
Math.sec()
Math.sech()
Math.sigmoid()
Math.sign()
Math.sinc()
Math.sinh()
Math.sq()
Math.tanc()
Math.tanh()
Math.vers()