Version B.13, Frank P. Westlake, Mar 15 2009.
MAPM Library Version 4.9.5  Copyright (C) 1999-2007, Michael C. Ring
C++ interface by Orion Sky Lawlor, maintained by Michael Ring.

Please report problems to Frank Westlake at <fp.westlake@yahoo.com>.

*****************************************************************************
DESCRIPTION
MATH performs mathematics on algebraic expressions. Values are retained as fractions with the numerators and denomonators of arbitrary precision and mathematical operations are performed on the fractions. Floating point roundoff occurs only when an operation requires a floating point number, such as with the trigonometric functions, and when the selected precision is exceeded. Expressions are input through the command line, from files, and from the environment. Output is to the console but the solution and any intervening results may also be saved as variables in the environment and in disk files.

*****************************************************************************
COMMANDLINE OPTIONS
 /,         Replace the default radix point of '.' with ','. See /RadixChar below for more options.

            Example: MATH /, 101,3   Solution: 202,6

 /^^        Swap the XOR operator and the power operator so that '^' is the power operator and '**' is the XOR operator. This switch is actually '/^' but in the Windows console '^' is the escape character so it must be used to escape itself, or the whole switch must be quoted ("/^"). Alternatively, '/**' is available to accomplish the same function.

 /_         Check for and convert repeating digits during both input and output. For example, if the value input is 0.123123 the repeating pattern of '123' will be translated to the fraction 123/999. During output the value 0.123123123123 will be converted to 0._123 or to [41/333] depending on the selected output format. Conversion may be specified for only input or only output with '/I:_' and /O:_'.

            Example: MATH /_      0.123123   Solution: 0._123
            Example: MATH /_ /O:F 0.123123   Solution: [41/333]

 /A         Print the solution in all number bases from -62 through 62 and in Roman numerals. For this feature, the base 1 representation is only printed if it is less than 100. The intent of this feature is to permit a visual comparison of the value in all supported number bases. If the switch is suffixed with the equal sign ('/A=') then balanced bases 2 through 26 will be printed instead.

 /BI=base   Number base of input numbers is 'base'.
 /BO=base   Number base for output numbers is 'base'.
 /B[=base]  Optionally specify the number base for both input and output. If '/B' is indicated without 'base', all values will be examined for a base indicator. A base indicator is a two-character prefix beginning with the character '0' and ending with the highest value in the base set. For example, the value 1 in bases 2, 8, 10, 16, and 62 is: 011, 071, 091, 0F1, and 0z1 respectively; but only if the '/B' switch is indicated. Without the '/B' switch, values preceded by '0b', '0o', and '0x' are base 2, base 8, and base 16 respectively. Preceeding zeroes are otherwise ignored so the traditional octal notation (i.e. 037) is ineffective. With or without the switch '/B', the base suffix (i.e. 10[16] for base 16) is always recognized and takes precedence over the base prefix. If both are used the prefix is discarded. This parameter also causes the output to include the base indicator.

            Example: MATH /bi=16 /bo=2 FF*3  Solution: 1011111101 (765 base ten)
            Example: MATH /bi=16       FF*3  Solution: 765 (base ten)
            Example: MATH /b    0FFF * 0111  Solution: 09765 (765 base ten)

 /BaseSet=
 /BaseSetIn=
 /BaseSetOut=
            Specify the set of characters for the number base. The default base set is:
              0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

            That is the characters 0-9, followed by A-Z, then followed by a-z. This base set supports a maximum base of 62 and a minimum base of -62. In the default set, if the base is -36 through 36 then the alphabetic characters are not case sensitive and az[36] is equivalent to AZ[36]. If the base set is changed with this parameter then all bases will be case sensitive.

            Example: MATH /BaseSet="ABCDEFGHIJ"    BAB*D   Solution: DAD
            Example: MATH /BaseSetIn="ABCDEFGHIJ"  BAB*D   Solution: 303
            Example: MATH /BaseSetOut="ABCDEFGHIJ" 101*3   Solution: DAD

 /C         Print the internal table of constants.

 /F[=path]  Store and read variables as disk files instead of as environment variables. The current directory will be used unless 'path' is specified. These files are normal ASCII text files. Variables with names prefixed with the character '$' are temporary and will be deleted when the program exits, even if it is a preexisting variable. The prefix need only be applied once. Some versions of Windows will not permit the value of environment variables to be retained after program exit; file variables must then be used.

            Example: MATH /F         price=25,  quantity=6,  cost=price*quantity
            Example: MATH /F=%TEMP%  price=25,  quantity=6,  cost=price*quantity
            Example: MATH /F        $price=25, $quantity=6, $cost=price*quantity

 /I=[option]
            Input format. 'option' may be one or more of the following:

            _  Check for and convert repeating digits. See '/_' above for details.

               Example: MATH /I:_  0.123123   (0.123123 becomes [41/333] internally.)

            B  Examine values for a base indicator. See '/B' above for details.

               Example: MATH /I:B 09123  (09123 becomes 123 base ten internally.)

            R  All input values are Roman numerals. To mix Roman numeral input with other input types, see 'MATH /? roman()'.

               Example: MATH /I:R V*X  Solution: 50

 /[         Brackets will not be printed to delimit fractions. Fractions are normally delimited by brackets so that if output is used later as input the value will be read as a fraction instead of as a division operation.

            Example: MATH /o:f    2*[1/3]  Solution: [2/3]
            Example: MATH /o:f /[ 2*[1/3]  Solution:  2/3

 /O[=option]   Output format. 'option' may be one of the following (example value is 123456789000.987):

            N  Scientific                (1.23456789000987\+11).
            E  Engineering               (123.456789000987\+9).
            F  Fraction                  ([123456789000987/1000]).
            I  Integer                   (123456789000).
            R  Roman numeral             (MCCXXXIVS'DCLXXVIIIS'MMMMS.....).

            Some of the above may be modified by one or more of the following (i.e. /O:RFX)

            B  Base suffix               (1.23456789000987\+11[10]). Modifies: All.
            P  SI prefix                 (123.456789000987 giga-). Modifies: E.
            S  Short class               (123.456789000987 billion). Modifies: E.
            L  Long class                (123.456789000987 milliard). Modifies: E.
            F  Fraction                  ([123456789000987/1000]). Modifies R.
            M  Mixed Fraction            (123456789000+[987/1000]). Modifies: F, R.
            X  Exponential magnitude     (123456789\+3). Modifies: I, F, R.
            O  Arithmetic round integers (123456789001). Modifies: I, R.
            [  No brackets.              (123456789000+987/1000). Modifies: F, FM, R, RM.

            Use '/O' without 'option' to sample the various formats.

 /P         Precision; the number of digits to retain.

            Example: MATH       1/3  Solution: 0.333333333333333333333333333333
            Example: MATH /p=10 1/3  Solution: 0.3333333333

 /R         All input and output values are Roman numerals. For mixing Roman numerals with other types, see 'MATH /? roman()'.

            Example: /R V*X  Solution: L

 /?[W|B] [/V]
            Print this document. '/V' is for verbose output. Optionally select buffer word wrap ('/?B') or window word wrap ('/?W') (default).
 /?[W|B] [function]
            Print descriptive information for 'function'. Wildcards * and ? are accepted. Optionally select buffer word wrap ('/?B') or window word wrap ('/?W') (default).

            Example: MATH /? c*d  Solution: crd(n)              Chord of n.

 /RomanSet='set'
            'set' is a comma delimited list of glyphs to use in place of the default set of ".,S,I,V,X,L,C,D,M". Not all glyphs must be replaced and trailing commas may be ommitted. For example, to replace "I" with "j" and "D" with "I)": /RomanSet=,,j,,,,,I) OR /RomanSet=,,j,,,,,I),

            Example: MATH /RomanSet=,,j,,,,,I) /O:R 833*2  Solution: MI)CLXVj
            Example: MATH /RomanSet=[1/12],[1/2],[1],[5],[10],[50],[100],[500],[1000] /o:r 19999/12  Solution: [1000][500][100][50][10][5][1][1/2][1/12]

 /MagnitudeStr='str'
            Replace the default magnitude indicator of '\' with 'str' for both input and output. Replacing the default indicator can cause conflicts. If the replacement is alphanumeric, such as the conventional indicator of 'E', then conflicts will occur in number bases that use that character. If the replacement contains operators, such as in " * 10^", then the algebraic engine will misinterpret those operators. The default indicator '\' was chosen because it does not conflict in any way and because it has a history of the same function in some computer systems.

            Example: MATH /MagnitudeStr=E 5E3/5  Solution: 1000

 /RadixChar='char'
            Replace the default radix point of '.' with 'char' for both input and output. Since the comma is a very common replacement, the switch '/,' is available for that replacement alone.

            Example: MATH /RadixChar=' 123'4*2  Solution: 246'8

 /illion='str'
            Replace the default number name suffix of 'illion' with 'str' for both input and output.

            Example: MATH /O:L /illion=iljoen 10**18  Solution: 1 triljoen

 /illion='str'
            Replace the default number name suffix of 'illion' with 'str' for both input and output.

            Example: MATH /O:L /illiard=iljard 10**15  Solution: 1 biljard

*****************************************************************************
OPERATORS
A comment may be inserted following the '#' character and persists until the end of the line. 

Operator Precedence
There might be some minor changes but in this version the precedence is as follows:
    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
0:  ,   )   ]   }   :   ;  :=  
1:  =  *=  /=  %=  +=  -=  &=  ^=  |= <<= >>=
2:  ?
3: ||
4: &&
5:  |
6:  ^
7:  &
8: ==  !=
9:  <  <=   >  >=
A: <<  >>
B:  +   -
C:  *   /      32
D: **
E:  !   ~   +   -  ++  -- 248   '   "
F:      (   [   {

Operator definitions
The four columns in the table below are: hex value, symbol, format, description. The letters in the format description are: V=variable, n=number, F=function, E=expression, and A and B are both expressions.

Termination:
00 ,   E,E,E  Expression seperator.
01 )   (E)    End of a grouping. See F1.
02 ]   [V]    End of a grouping. See F2.
03 }   {E}    End of a grouping. See F3.
04 :   E?E:E  A member of the '?:' ternary operator pair. See 20.
05 ;   E;     Expression terminator.
Assignment:
06 :=  V:=E   Assignment of the expression on the right to the variable on the left without evaluating the expression.
10 =   V=E    Assignment of the value of the expresion on the right to the variable on the left.
11 *=  V*=E   Multiplies the value of the expression on the right with the value of the variable on the left and stores the solution in the variable on the left.
12 /=  V/=E   Divides the value of the expression on the right with the value of the variable on the left and stores the solution in the variable on the left.
13 %=  V%=E   Integer remainder of division of the value of the expression on the right with the value of the variable on the left and stores the solution in the variable on the left.
14 +=  V+=E   Adds the value of the expression on the right to the value of the variable on the left and stores the solution in the variable on the left.
15 -=  V-=E   Subtracts the value of the expression on the right from the value of the variable on the left and stores the solution in the variable on the left.
16 &=  V&=E   Bitwise AND of the value of the expression on the right with the value of the variable on the left and stores the solution in the variable on the left.
17 ^=  V^=E   Bitwise XOR of the value of the expression on the right with the value of the variable on the left and stores the solution in the variable on the left.
18 |=  V|=E   Bitwise OR of the value of the expression on the right with the value of the variable on the left and stores the solution in the variable on the left.
19 <<= V<<=E  Bitwise shift left of the value of the variable on the left by the value of the expression on the right and stores the solution in the variable on the left. Because of arbitrary precision and fractions, this has been implemented as multiplication.
19 >>= V>>=E  Bitwise shift right of the value of the variable on the left by the value of the expression on the right and stores the solution in the variable on the left. Because of arbitrary precision and fractions, this has been implemented as division.
Logical:
20 ?   E?E:E  Ternary operation (TEST ? TRUE : FALSE). The expression preceeding '?' is evaluated as either true or false. If true, the expression immediately following the '?' becomes the solution; this true solution is terminated with a ':'. If the expression preceeding  the '?' is false then the expression immediatley following the ':' becomes the solution; this false solution is terminated by the the end of the string, end of a grouping, or the comma. To use within an expression enclose the entire sequence in parentheses. In the example 'z=5+(a+1?b*2:b/2)+1', if 'a+1' is true (not zero) the resulting expression becomes 'z=5+b*2+1', but if 'a+1' is false (zero) the resulting expression becomes 'z=5+b/2+1'. The expression which is not chosen will not be evaluated.
30 ||  A || B Logical OR. If A is true the solution becomes 1 and B is not evaluated. If the A false then the right side becomes the solution after evaluation: 1 if true, 0 if false. It is important to note that B is not evaluated if A is true, so if B contains an assignment operator the assignment will not be performed. For example, in the expression 'z= 1+1 || b+=2' it might be expected in later expressions for 'b' to have had the value 2 added to it, but that will only occur if 1+1 were not true.
40 &&  A && B Logical AND. A is evaluated and if it is true then B is evaluated. The solution is 1 if they are both true or 0 if they are not both true. It is important to note that B is not evaluated if A is false, so if B contains an assignment operator the assignment will not be made. For example, in the expression 'z= 1*0 || b+=2' it might be expected in later expressions for 'b' to have had the value 2 added to it, but that will only occur if 1*0 were not false.
Bitwise:
50 |   A |  B Bitwise OR. The solution is the value resulting from the combination of the on bits of both A and B. 0b0101 | 0b0010 = 0b0111.
60 &   A &  B Bitwise AND. The solution is the value resulting when only the bits which are on in both A and in B are taken. 0b0101 & 0b1100 = 0b0100.
70 ^   A ^  B Bitwise XOR. The solution is the value resulting when the bits which are on in either A or in B, but not in both, are taken. 0b1010 ^ 0b1100 = 0b0110.
Comparison:
80 ==  A == B Is equal. If A is equal to B then the solution becomes 1; otherwise it becomes 0. In some cases it will be necessary to store the expressions in variables then compate the variables, ex: math /p=2 t=tan(1), cs=sin(1)/cos(1), t==cs
81 !=  A != B Is not equal. If A is not equal to B then the solution becomes 1; otherwise it becomes 0.
90 <   A <  B Is less than. If A is less than B then the solution becomes 1; otherwise it becomes 0.
91 <=  A <= B It less than or equal. If A is less than or equal to B then the solution becomes 1; otherwise it is becomes 0.
92 >   A >  B Is greater than. If A is greater than B then the solution becomes 1; otherwise it becomes 0.
93 >=  A <= B Is greater than or equal. If A is greater than or equal to B then the solution becomes 1; otherwise it is becomes 0.
Arithmetic:
A0 <<  A << B The value of A is increased by shifting all the bits to the next greater position a number of times equal to the value B. Bits are a placeholder in base 2 so the resulting arithmetic is A*2**B (A times 2 raised to the power B).
A1 >>  A >> B The value of A is decreased by shifting all the bits to the next lower position a number of times equal to the value of B. Bits are a placeholder in base 2 so the resulting arithmetic is A/2**B (A divided by 2 raised to the power B).
B0 +   A + B  The sum of the values of A and B.
B1 -   A - B  The sum of the values of A and -B.
C0 *   A * B  The product of the values of A and B.
C1 /   A / B  The product of the values of A and the inverse of B.
C2              Currently unassigned.
C3     n n    Implied multiplication: number*number. This feature might be removed if conflicts become apparent.
       nF     Implied multiplication: number*function. This feature might be removed if conflicts become apparent.
       nV     Implied multiplication: number*variable. This feature might be removed if conflicts become apparent.
D0 **  A**B   The product of the value of A and itself B times. The power of A raised B times.
E0 !   A!     The factorial of A. For non-integers the gamma function is used.
       !A     If A is true then the solution becomes 0; otherwise it becomes 1.
E1 ~   ~A     The solution is the bitwise complement of A (each bit is inverted).
E2 +   +A     Cast to positive. Not implemented.
E3 -   -A     Cast to negative. Not implemented.
E4 ++  ++V    Increase the value of variable V by 1 and store the result in V, then use the result.
       V++    Take the value of V for use then increase the value of the variable by 1.
E5 --  --V    Decrease the value of variable V by 1 and store the result in V, then use the result.
       V--    Take the value of V for use then decrease the value of the variable by 1.
E6 248 A*     The solution is a A*PI/180, the conversion of degrees to radians. NOTE: * is representing ASCII 248, the degree symbol. 
E7 '   A'     The solution is a A*PI/10800, the conversion of minutes to radians.
E8 "   A"     The solution is a A*PI/648000, the conversion of seconds to radians.
Grouping:
F0              Currently unassigned.
F1 (   (E)    Isolates a portion of an expression. All operator precedences apply only within the matched and paired grouping symbols.
F2 [   [E]    Context sensitive. Identifies either a fraction ([1/2]) or a number base (50[10]). Ex: [1/2][10].
F3 {   {E;E}  Groups expressions in a user defined function.

*****************************************************************************
NUMBERS
Internally a number is defined as (in C):
struct
{
	MAPM	n;	//Numerator
	MAPM	d;	//Denominator
	MAPM	e;	//Magnitude
	DWORD	s;	//Status
	BOOL	b;	//In use
}	NUMBER;	//[n/d]*10**e

MAPM is Michael C. Ring's data type for an arbitrary precision floating point value.

During mathematical operations the number is manipulated as the fraction:

   [n/d]\e

with n=numerator,
     d=denominator,
     e=magnitude (i.e.   [n/d]*10**e).

*****************************************************************************
INPUT
Use standard algebraic notation; i.e 1+2*3**4*5+6 is equivalent to 1+(2*(3**4)*5)+6 and 3**4*2*5+1+6.

The general format for number input is the fraction:

   [n/d]\e[b]

with n=numerator,
     d=denominator,
     e=magnitude ( *10**c, with '10' being in base d),
     b=the number base.

All values 'n', 'd', and 'e' may be integers, floating point numbers, internal constants, or names of variables. 'd' must be an integer. The brackets permit assignment to numerator and denominator without losing precision by performing the division. Not all items are required; the following are also accepted: n; n\e; n[b]; n\e[b]; [n/d]; [n/d]\e; and [n/d][b]. 'n' and 'd' may also be of the format: a\e[b], a\e, a[b], with 'a' being either the numerator ('n') or denominator ('d'). For example, the value of one-half may be entered as any of the following: 

  0.5             One half in base 10.
  0.8[16]         8/10 in base 16.
  [1/2]           The fraction one half in base 10.
  [2/5][8]        The fraction 2/5 in base 8.
  [2[8]/5[8]]     The fraction 2/5 in base 8.
  5\-1            Five times ten to the minus one in base 10.
  [1/2]\-1[8]     The fraction one half in base 8 times 8 to the minus 1.
  and others.

*****************************************************************************
VARIABLES
Names of variables are not case sensitive.

Variables may consist of a complete expression, not just a numerical value.

  Example: MATH poly1:=5*x**2+3*x+1
  Example: MATH x=2, z=poly1

A variable may also be defined as a function with a parameter list for input. Following are two functions defined on the command line:

  Example: MATH FtoC(F):=5(F-32)/9, FtoC(98.6)  Solution: 37
  Example: MATH max($a, $b):={a>b?a:b;} Comments OK beyond right brace ('}').
  Example: MATH max(3, 4)                       Solution: 4

A function defined with a text editor is not constrained to a single line. Expressions are terminated by comma or semicolon and grouped within braces. The variable begins with the parameter list (with parameters defined as temporary if desired), the definition operator ':=', then followed by a single expression or braces grouping multiple expressions:

  FILENAME: DayOfWeek()
  -- FILE BEGINS ON NEXT LINE --
  ($y,$mm,$d):=
  {
    $cy=y-(mm<3?1:0);
    $cc=ipart(cy/100);
    y=cy-cc*100;
    # Comment lines begin with the number sign.
    mm=((mm-14)%12)+12;
    cy=d+floor(2.6*mm-0.2)-2*cc+y+floor(y/4)+floor(cc/4);
    mod(cy,7);
  }
  In this beta version nothing is read after the closing brace
  so this part of the file may consist of anything. It will
  probably remain so in future versions.
  -- FILE ENDS ABOVE THIS LINE --

Using the appropriate software the above variable could also be defined in an environment variable.

In the following example a portion of the commandline is enclosed in quotes because it contains the character '<', which is a redirection operator to the command interpreter:

  Example: MATH "WCF(Farenheit,wMPH):=(wMPH<=3)?Farenheit:(35.74+0.6215*Farenheit-35.75*(wMPH**0.16)+0.4275*Farenheit*(wMPH**0.16))"

Names of variables begin with an alphabetic character and may thereafter consist of both alphabetic and numeric characters. There is no limit on name length.

Variables exist either in the environment (default) or in disk files. Both types of variables may be used in the same expression if file-based variables are prefixed with the character '@', for example, 'r' is in the environment and 'z' is in a disk file:

  Example: MATH r=10, @z=2, r*z

If the /F switch is used, variables will all be in disk files in the current directory, or in the directory specified following the /F switch, and the prefix character is not needed.

  Example: MATH /F        r=10, z=5*r
  Example: MATH /F=%TEMP% r=10, z=5*r

If a variable is defined in the environment it cannot be used when the '/F' switch is specified. A future version might use '/F' to switch the meaning of '@' from 'file' to 'environment'.

File-based variables may also include an absolute or relative path. For example, the variable 'z' as the file 'C:\math\vars\z' may be expressed either as '@C:\math\vars\z', as 'vars\z' if the current directory is 'C:\math', or as 'z' if the current directory is 'C:\math\vars' or the commandline parameter '/F=C:\math\vars' is used. A Unix convert could use '..\..\math\vars\z' from within 'C:\math\vars' if it becomes psychologically necessary.

  Example: MATH    @C:\math\vars\r=10, @C:\math\vars\z=5 * @C:\math\vars\r
  Example: MATH /F  C:\math\vars\r=10,  C:\math\vars\z=5 *  C:\math\vars\r
  Example: MATH /F=C:\math\vars  r=10,  z=5r

If names of variables are prefixed with the character '$' they are temporary and will be deleted before the program exits -- even if it is a preexisting variable. The file-based variable prefix '@' may be placed either before or after the temporary-variable prefix ('$@' or '@$'). The prefix need only be applied once to mark the variable as temporary.

  Example: MATH $r=10, $z=5*r
  Example: MATH @$r=10, $@z=5*r

MATH could be used to clean up the environment by defining existing variables as temporary then exiting:

  Example: MATH a=5, b=10, c=15, d=a*b*c
           MATH $a, $b, $c, $d

Some versions of Windows will not permit the value of environment variables to be retained after program exit; file variables must then be used. This program was written on Windows Vista Home Basic and everything works in that OS as described herein, but I had a 64-bit dual processor Windows Vista Home Basic machine for a week and could not get the program to write to a parent processes environment. The problem might have been solved but I no longer have the computer to make the test.

When in number bases greater than 10 use caution with variable name assigments; the string of alphanumeric characters could be read as either a variable name or as a number. For example, in 'MATH /BI=16 (2*BE)||!(2*BE)', if 'BE' be a variable it will in some cases be read as the variable 'BE' and in other cases be read as the hexadecimal value BE. Some precautions to employ are:

 - Use the base-indicator prefix described under "NUMBER BASES". Numbers will then always begin with a numeric character and cannot be misread as a variable name (i.e. '0FBE').

 - Use tempory variables. Variable names beginning with '$' will not be misread as a number (i.e. '$BE").

 - Use file variables with the file variable prefix '@' to ensure that names will not be misread as numbers (i.e. '@BE' or '$@BE').

*****************************************************************************
CONSTANTS
In this current configuration an internal constant is a predefined variable which may be redefined. The name of the constant is first searched for in either the environment or on the disk, as applicable, and if not located it is searched for in the list of internal constants. To prevent this supercession, prefix the name of the constant with the backquote character ('`'), ASCII 96.

Names of constants are not case sensitive.

List of Constants
  E      2.718... calculated to precision (/p='precision')
  PI     3.141... calculated to precision (/p='precision')
  PI_2   PI/2     calculated to precision (/p='precision')
  PI2    PI*2     calculated to precision (/p='precision')

  Example: MATH /p=6        r=1,  pi*r**2  Solution: 3.14159
  Example: MATH /p=6  pi=3, r=1,  pi*r**2  Solution: 3
  Example: MATH /p=6  pi=3, r=1, `pi*r**2  Solution: 3.14159

Note that in the later example, even with PI defined as 3, the backquote permits the more accurate value.

*****************************************************************************
NUMBER BASES
In the default configuration this program can input and output numbers in bases -62 through 62, and balanced bases 2 through 26. These limitations are due the quantity of characters available and because the programmer hasn't yet figured out how to convert numbers to and from negative balanced bases.

Values may be suffixed with the number base enclosed in brackets.

  Example: MATH 10[2] + 10[8] + 10  Solution: 20, base 10
  Example: MATH /O:F [1/3][2] * 2   Solution: [4/3], base 10

Bases may be specified seperately for input and output:

  Example: MATH /BI=2 /BO=16 "110101 & 101010"  Solution: 20

For versitility there is also an unorthodox method of indicating the number base which is applicable only when the switch '/B' is specified. With this method it is assumed that any value beginning with the digit for zero has as its second character the highest numeral in the number base. In the following table the value 32(base 10) is shown in various bases with this base indicator prefix:

  BASE   VALUE OF 32(base10)
   2      01100000
   8      0740
   10     0932
   16     0F20
   32     0V10
   62     0zW

  Example: MATH /b 095/092     Solution: 092.5  (5/2 == 2.5)
  Example: MATH /b 090.5*0910  Solution: 095    (0.5*10 == 5)

*****************************************************************************
BASE SETS
There are two sets of characters used for number bases; one set is for unbalanced bases and the other for balanced bases:

  Unbalanced: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
  Balanced:   zyxwvutsrqponmlkjihgfedcba0ABCDEFGHIJKLMNOPQRSTUVWXYZ

In the default balanced base, upper case letters are positive and lower case letters are negative and zero is represented by '0'.

Base sets may be redefined for both input and output together or seperately:

  Example: MATH /BaseSet="ABCDEFGHIJ"    BAB*D   Solution: DAD
  Example: MATH /BaseSetIn="ABCDEFGHIJ"  BAB*D   Solution: 303
  Example: MATH /BaseSetOut="ABCDEFGHIJ" 101*3   Solution: DAD

  Example: MATH /BalSetOut=-0+  /bo=3=   3+2     Solution: +--
  Note: The characters '+' and '-' should not be used in the input base set because they will be read as mathmatical operators and not as numbers.

*****************************************************************************
ROMAN NUMERALS
During the design of this Roman numeral implementation the following articles were used for reference:
Wikipedia: Roman_numerals
http://www.web40571.clarahost.co.uk/roman/howtheywork.htm

This program uses some non-standard procedures to depict numerals of the Roman numeral character set. These procedures were adopted for the following reasons:

  1. Not all glyphs are available in the ASCII 5-bit character set. They are available in Unicode but I wanted to support 5-bit ASCII.

  2. Larger numbers are in common usage now then were when Roman numerals were in common usage and the character set available with 5-bit ASCII does not adequately support these large numbers.

  3. This program uses arbitrary precision numbers so big numbers can get very big and make conventional Roman numerals unusable.

No characters have been added to the Roman numeral character set. This program makes use of the standard character set "M D C L X V I" for whole numbers and the set "S ." for fractional values, but the sets are arranged with 'S' (semis) as part of the first set -- not as a set of whole numbers, but as a set which will be repeated. This transition was necessary to complete the pattern of 10^n/2 and 10^n for n from 0 to 3 as shown below:

  10^n/2  10^n
    [S]    I    n=0
     V     X    n=1
     L     C    n=2
     D     M    n=3

With the pattern balanced in this manner it can be meaningfully repeated along the number line in groups of 10,000. To represent values greater than 10^4-1 (9999) the pattern of this set is repeated and the apostrophe (') is used to seperate groups of 10,000. Historically, the apostrophus had been used in various ways to adapt the character set for larger values, and some of these adaptations became additional characters in the set; so the apostrophe and its general meaning is not herein an addition to the set, but it is a continuation of its usage to adapt. Few other characters are available to serve as a group seperator because most perform mathematical or control operations. If there are no values in lesser positions the apostrophes must accululate.

In classical Greek the name for a number of 10,000 is "myraid". This name is useful in reading large Roman numbers. For example, instead of trying to read "CS'" as "one hundred ten-thousands and half a ten-thousand", or to mentally calculate it as "1,005,000", it can be read as "one hundred and a half myraid."

The subtractive rule cannot be used across an apostrophe. To do so would require bringing a numeral from the right side of an apostrophus over to the left, thereby incorrectly multilying its value by 10,000. Therefore the value MI' is one thousand and one myraid ((M + I) * 10,000), and not 9,000 (I * 10,000 - M) which should be represented as "S'MMMM"; and the value MS' is one thousand and a half myraid ((M + S) * 10,000), and not 4,000 (S * 10000 - M) which should be represented as "MMMM". Between apostrophes the subtractive rule is applied normally.

The following table shows the available glyphs and subtractive pairs through three sequences of the repeatable pattern.

(TRADITIONAL)
        S         I        IV         V        IX         X        XL
      0.5         1         4         5         9        10        40   

        L        XC         C        CD         D        CM         M
       50        90       100       400       500       900      1000


(EXTENDED)
       S'        I'       IV'        V'       IX'        X'       XL'
     5000     10000     40000     50000     90000    100000    400000

       L'       XC'        C'       CD'        D'       CM'        M'
   500000    900000   1000000   4000000   5000000   9000000  10000000

      S''       I''      IV''       V''      IX''       X''      XL''
 0.5*10^8    1*10^8    4*10^8    5*10^8    9*10^8   10*10^8   40*10^8

      L''      XC''       C''      CD''       D''      CM''       M''
  50*10^8   90*10^8  100*10^8  400*10^8  500*10^8  900*10^8 1000*10^8


As a user selectable alternative a more modern adaption has been implemented, and that is to remove the trailing apostrophes and to represent them as a magnitude in the same manner as other number systems (10^64 == I'''''''''''''''' == I\XVI == one times one myraid to the 16th power). In this manner, large values with a relatively small quantity of significant figures can be easily represented with the Roman numeral character set.

Some examples:

     DECIMAL   ROMAN             KNUTH'S MYRAID SYSTEM
        4999   MMMMCMXCIX        (Fourty-nine hundren ninty-nine.)
        5000   S'                (Fifty hundred, or one half myraid.)
        5001   S'I               (Fifty hundred one, or one half myraid and one.)
      10,000   I'                (One myraid.)
      10,001   I'I               (One myraid one.)
        10^8   I''               (One myllion, or one myraid myraid.)
  1666*10^12   MDCLXVI'''        (Sixteen hundred sixty-six myraid myllion.)
       10^64   I'''''''''''''''' (One quadryllion.)
       10^64   I'''''''''''''''' (One quadryllion.)

Values of less than 1 are rounded to the nearest twelth (1/12), with two exceptions: any value less than 1/12, however slight, will be rounded up to 1/12, and any value greater than 11/12 but not yet 12/12 will be rounded down to 11/12. The reasoning is that any part of an object is still an object and is therefor not nothing, and any that any object which is missing any part, however small, is not a whole object. The characters 'S' and '.' are used normally to depict 1/2 and increments of 1/12 respectively. These fractional values are appended to the integer value if existing. Some examples:

     0.25 = ...           Three twelths.
     0.75 = S...          Nine twelths.
     1.25 = I...          One and three twelths.
     1.75 = IS...         One and nine twelths.
   5000.5 = S'S           Fifty hundred and six twelths.
  6666.66 = S'MDCLXVIS..  Sixty-six hundred sixty-six and eight twelths
                          (rounded up by the quantity 0._6\-2).

There is no character for zero -- zero is simply nothing -- but to make output more easily machine readable the space character will be output for zero.

ROMAN NUMERAL SET
The Roman numeral set consists of nine glyphs which may be redefined on the commandline. These glyphs may consist of more than one character each. The default set is defined as:

  . S I V X L C D M

If redefined, the positional value of each glyph will remain the same, and the same conventional subtractive rule will be applied to construct numbers.

Redefinition is accomplished by following the comandline switch '/RomanSet=' with the set of replacement characters seperated by commas. Not all glyphs must be replaced and trailing commas may be ommitted. For example, either of the following will replace "I" with "j" and "D" with "I)":

 /RomanSet=,,j,,,,,I)
 /RomanSet=,,j,,,,,I),

            Example: MATH                      /O:R 833*2  Solution: MDCLXVI
            Example: MATH /RomanSet=,,j,,,,,I) /O:R 833*2  Solution: MI)CLXVj
            Example: MATH /RomanSet=[1/12],[1/2],[1],[5],[10],[50],[100],[500],[1000] /o:r 19999/12  Solution: [1000][500][100][50][10][5][1][1/2][1/12]

FUNCTIONS
For user-defined functions see VARIABLES above.

The built-in functions are:
abs(n)              Absolute value n.
acos(n)             Arc whose cosine is n. 0=acos(1)
acosh(n)            Hyperbolic arccosine of n. 0=acosh(1)
arccos(n)           Arc whose cosine is n. 0=arccos(1)
arcsin(n)           Arc whose sine is n. 0=arcsin(0)
arctan(n)           Arc whose tangent is n. 0=arctan(0)
asin(n)             Arc whose sine is n. 0=asin(0)
asinh(n)            Hyperbolic arcsine of n. 0=asinh(0)
atan(n)             Arc whose tangent is n. 0=atan(0)
atan2(y,x)          Arc whose tangent is y/x.
atanh(n)            Hyperbolic arctangent of n. 0=atanh(0)
cbrt(n)             Cubic root of n.
ceil(n)             Smallest integer not less than n.
cos(n)              Cosine of n. 1=cos(0)
cosh(n)             Hyperbolic cosine of n. 1=cosh(0)
cot(n)              Cotangent of n.
covers(n)           Coversine of n.
crd(n)              Chord of n.
csc(n)              Cosecant of n.
digitsf(a)          The number of fractional digits. 2=digits(123.45)
digitsi(a)          The number of integer digits. 3=digits(123.45)
exp(n)              Exponential e to the power of n.
exponent(a)         The value of the exponent. 3=exponent(5*10**3)
float(n)            Expression n evaluated as floating point numbers.
floor(n)            Largest integer not greater than n.
fpart(n)            Fractional part of n.
frac(n)             Fractional part of n.
gamma(n)            Value of the gamma of n.
gcd(a,b [,...])     Greatest divisor common to all arguements.
gcdx(a,b)           The x solution of the extended greatest divisor. -1=gcdx(10, 15)
gcdy(a,b)           The y solution of the extended greatest divisor. 1=gcdy(10, 15)
gln(n)              Value of the log of the gamma of n.
hav(n)              Haversine of n.
hypot(a,b)          Hypotenuse of right triangle with sides a and b.
int(n)              Expression n evaluated as 64-bit integers.
ipart(n)            Integer part of n.
isprime(n)          1 if n is prime, 0 if not. 1=isprime(3)
lcm(a,b [,...])     Lowest multiple common to all arguements.
ln(n)               Natural logarithim of n.
lng(n)              Value of the log of the gamma of n.
log(n)              Logarithm of n in base 10. 1=log(10)
log10(n)            Logarithm of n in base 10. 1=log(10)
log2(n)             Natural logarithim of n.
logb(b,n)           Logarithm of n in base b.
magnitude(a)        The value of the magnitude. 10**3=magnitude(5*10**3)
mod(x,y)            x modulo y, the remainder of x/y.
modf(n,v)           Returns the fractional part of n and stores the integer part in variable v.
nCr(a,b)            Combinations of a taken b at a time, without repetition. 120=nCr(10,3)
nCrr(a,b)           Combinations of a taken b at a time, with repetition. 220=nCrr(10,3)
nPr(a,b)            Permutations of a taken b at a time.
poly(x,d,{c,...})   Value of the polynomial of x in degree d with coefficients such that c[d]*x**(d)+c[d-1]*x**(d-1)....
pow(x,y)            x to the power of y.
pow10(n)            10 to the power of n (10**n). 100=pow10(2)
prod(n,v,l,h)       Product of expression n with variable v at values from l to h.
rand([n])           A random 64-bit integer optionally limited to less than n.
roman(s)            The value of the Roman numeral depicted by 's'.
round(n,d)          n rounded (arithmetic) to d places.
roundx(n,d)         n rounded (arithmetic) to d places.
sec(n)              Secant of n.
seq(n,v,l,s,h)      List generated by evaluating expression n with variable v at values from l to h in increments of s.
sigma(n,v,l,s,h)    Sum of the list generated by evaluating expression n with variable v at values from l to h in increments of s.
sign(n)             Zero if n is 0, -1 if it is less than 0, or 1 if it is greater than 0.
sin(n)              Sine of n. 0=sin(0)
sinh(n)             Hyperbolic sine of n. 0=sinh(0)
sqrt(n)             Square root of n.
sum(l)              Sum of the comma delimited list l.
sum(n,v,l,h)        Sum of expression n with variable v at values from l to h.
sumseq(n,v,l,s,h)   Sum of the list generated by evaluating expression n with variable v at values from l to h in increments of s.
tan(n)              Tangent of n. 0=tan(0)
tanh(n)             Hyperbolic tangent of n. 0=tanh(0)
vers(n)             Versine of n.

fin
