
MFCalc
Martin Carradus takes us through his multi function calculator
!MFCalc performs numerical calculations on expressions typed into its Input slot when the 'Calculate' button is clicked upon. The slot may be cleared out either by typing Control with 'U', or by clicking on the 'Clear Entry' button.
The following can be typed into the 'Input' slot:
Remarks
Remarks begin with '/*' and end with '*/', and are totally ignored by !MFCalc.
Numerics
These are of Five types:
 Integers: e.g. 1234
 Exponented Integers: e.g. 1234E1 or 1234e+2
 Hexadecimal constants, which begin with '&', '&h' or '&H': e.g. &H1ab or &HADD. They are case insensitive.
 Octal constants, which begin with '&o' or '&O': e.g. &O0137
 Floating constants: They always have a decimal point in them and can also be exponented: e.g. .1234 or 1.25 or 2.3456e6 or 0.001E+5
Variables
A named storage location containing a numeric value.
These always begin with an alpha character or underscore, then continue with any alphanumeric or underscore. These are case sensitive and become available with the value zero wherever they are mentioned. Integer variables end with a '%', otherwise they are taken to be floating point, unless declared otherwise (see below). They also can be of any length up to the 256 character limit of the Input slot.
Examples: 'a' or 'A%' or '_HELLO' or 'var1%' or 'non_zero'.
Assignment of Variables
This is simply done by typing the variables name then '=' then some numeric expression to the right of that, which in turn may contain variable names. e.g. num0=1.0 or A%=B%+6 or _hello=_goodbye
These statements may optionally be preceded by the key word 'LET', in upper or lower case.
e.g. LET a=0.0 or let no%=2
Note that if you assign an integer variable a floating value, then it will be truncated to an integer.
e.g. let a%=2.5 gives a% the value 2
Multiple Assignments
Simply concatenate the assignments together with a colon between.
Example: a%=b%*6:let c%=a%+4:d=c%^2
Operators
You have already seen some of these above, they are:
 Addition and Subtraction: '+' and '' e.g. 1+2 or 4.02.0
 You may also negate expressions: e.g. a%=b%
 Multiplication and Division: '*' and '/' e.g. 6*7 or 1.0/2.0
!MFCalc will complain about division by zero by outputting a comment
if this happens.
Integer Division: 'div' or 'DIV', performs the division and then
truncates it to an integer. Also complains about division by zero.
e.g. '5.0 div 2.0' gives the value '2'.
Modular Arithmetic: 'mod' or 'MOD', gives the remainder upon division.
e.g. 5 MOD 2 gives the value '1'. Complains about MOD with respect to
zero.
Lastly raising a% to the power b% is denoted by 'a%^b%', and, unlike
the rest binds to the right, so 'a%^b%^c%' is taken as 'a%^(b%^c%)'.
So 3^1^2 is 3, not 9.
!MFCalc complains about raising zero to a zero or negative power.
Also beware of raising negative quantities to fractional powers.
As you can see, these expressions may be bracketed, but otherwise the
precedence of these operators is in reverse order to the list above,
going from performing powers at highest precedence, to addition and
subtraction at lowest precedence.
In all this, if !MFCalc can't make sense of the input line, it outputs
a 'Syntax Error' comment.
Combinations
The number of ways of picking r objects from n without regard
to the order of the objects is usually denoted by:
n
C
r
The 'combination' of r objects from n.
e.g. The number of ways of picking 1 object from 5 is 5,
but the number of ways of picking 2 objects from 5 is 10.
The operator in !MFCalc you use is 'NCR' or 'ncr', so
'5 ncr 1' yields a value of 5,
and '5 ncr 2' yields a value of 10.
You may use floating values, but !MFCalc complains if they
have any fractional places. !MFcalc also complains if either
of the values supplied is negative, or if the second value exceeds
the first.
If you exceed several hundred for either of the arguments, you will
get a message about 'Stack Overflow', as recursion is employed.
Lastly NCR binds the least of all the operators, so all calculations
on both sides are performed first before the combination is taken.
e.g. '61 ncr 31' will give you the value of '5 ncr 2'.
NB NCR is not associative, so !MFcalc will error multiple NCRs
in one expression e.g. '12 NCR 2 NCR 2' will cause a syntax error.
Minimum and Maximum of Values
The operators 'MIN' and 'min' or 'MAX' and 'max' between two
expressions give the minimum or maximum of the two values e.g.
'2 min 1' gives a value of 1, but '2 max 1' gives a value of 2
These operators bind more tightly than addition or subtraction, but
less than multiplication and division or any higher operator, so,
'2 min 1 + 3 min 2', will give the sum '1 + 2' giving 3,
but '2*6 min 3*8' will produce '12 min 24', giving 12.
Also they are left associative, so combinations of 'min' and 'max' are
obeyed from left to right e.g.
'2 max 1 min 4' becomes '2 min 4', which becomes 2
You will note that you can obtain the minimum or maximum of more than
two values by simply concatenating them between the same operator e.g.
'x% min y% min z%' gives the minimum of x% and y% and z% and
'x% max y% max z%' gives the maximum of x% and y% and z%.
Both 'min' and 'max' attempt to keep the resulting value as an integer
whenever possible e.g.
'2.0 max 4.0' will produce the integer value of '4', not '4.0',
but '2 max 4.7' will produce the floating value '4.7'
Lowest Common Multiple (LCM) and Greatest Common Divisor (GCD)
The Greatest Common Divisor of two Numbers is the largest number less
than or equal to them that divides into both numbers exactly.
e.g. '6 gcd 21' gives 3, as 6=3*2 and 21=3*7, so 3 is the largest
common factor. !MFCalc uses a method called 'Euclid's Algorithm' to
obtain this number. If two numbers share no common factor greater than
or equal to two, then their GCD is one. This is true particularly when
both are prime.
The Lowest Common Multiple of two numbers is the lowest number that
shares the factors of both numbers.
e.g. '6 lcm 21' gives 42=3*2*7, as 6=3*2 and 21=3*7, 42 is the
smallest number that shares the factors of both numbers.
Note that that the LCM times the GCD of a and b is equal to (a times b)
for all a and b.
LCM and GCD both complain if either of the supplied numbers is zero or
negative or fractional. Both, also, always give out integer results.
(No decimal places shown.)
The operators 'gcd' and 'lcm' are on a par with 'min' and 'max' in
terms of priority  higher than addition or subtraction, but lower
than multiplication or division or raising to powers.
e.g. '3*2 gcd 3*7', will give the answer '3', as the multiplication is
performed first before the 'gcd'.
These operators are also associative, so you may obtain the LCM of x%,
y% and z%, by typing 'x% lcm y% lcm z%' in the 'Input:' slot and
clicking on 'Calculate'. If there is no operator of a higher
priority,'lcm' and 'gcd' are obeyed from left to right.
Mathematical Functions
There are twenty one of these available, and if the arguments are out of
range, !MFCalc complains. These functions need not have the
input expression in brackets and bind more tightly than any of the
operators. With trigonometric functions there are buttons on the
'SetUp' panel to select calculation in degrees, radians or grads.
 'ABS' or 'abs'  Absolute positive value without the sign.
 'ACS' or 'acs'  Arccosine.
 'ASN' or 'asn'  Arcsine.
 'ATN' or 'atn'  Arctangent.
 'COS' or 'cos'  Cosine of the Angle given.
 'COSH' or 'cosh'  Hyperbolic cosine.
 'EXP' or 'exp'  Raising e to the given power.
 'FRAC' or 'frac'  Fractional part of the given number. Negative if the number is negative.
 'INT' or 'int'  Truncate to the integer below.
 'FIX' or 'fix'  Round to nearest integer. If negative, rounds down, if positive, rounds up.
 'LN' or 'ln'  Natural logarithm to base e.
 'LOG' or 'log'  Logarithm to base ten.
 'RND', 'rnd', "RAND", or "rand"  Gives out a random number in the range 0  1 (inclusive). Does not take in any value as an argument.
 'SGN' or 'sgn'  The 'sign' of the number, 1 if negative, 0 if zero, +1 if positive.
 'SIN' or 'sin'  Sine of supplied angle.
 'SINH' or 'sinh'  Hyperbolic sine.
 'SQR' or 'sqr'  Square root, complains if supplied number is negative. Additionally, 'SQRT' or 'sqrt' will also be accepted.
 'TAN' or 'tan'  Tangent of supplied angle.
 'TANH' or 'tanh'  Hyperbolic tangent.
 'CBR' or 'cbr'  Cube root, turns negative if supplied number is negative. Additionally, 'CBRT' or 'cbrt' will also be accepted.
 'LNFACT' or 'lnfact'  The natural logarithm of the factorial of the supplied argument. The factorial of a number is the product of the number with all the ones below it down to 1, so 3 factorial is 3.2.1=6 and 4 factorial is 4.3.2.1=24. The natural logarithm is taken because factorials grow large very quickly, so the logarithm slows this process down and stops numeric overflow at higher values. As with 'ncr', very large arguments cause a 'Stack Overflow' message.
In addition, the key word 'PI' or 'pi' in a calculation gives out the
numeric value of the trigonometric constant pi.
All of these function names are reserved words and should not be used
for variable names.
As already mentioned, these functions bind more tightly than any other
operator, so, for example, the value of 'SIN 90 +2' is 3.0, not the
Sine of 92, when in degree mode. Note that 'SIN' is separated from 90
so that the reserved word 'SIN' can be recognised. If you had typed
'SIN90+2', a variable name 'SIN90' would be created, given a floating
value of 0.0 and 2.0 added, so 2.0 would be output. Note, also, that
if you had really wanted the Sine of 90+2, you should have used
brackets and put 'SIN(90+2)'.
The Form of the Calculated Value
The form (integer or floating point (double precision)) of the
expression being calculated is always at the level of the highest
operand, so, 2+3 gives an integer value of 5, and 5/2 gives an integer
value of 2, but 2+3.0 gives a floating value of 5.0, and 5/2.0 gives a
floating value of 2.5. If you had meant an integer divide to be
performed, then you should have used 'DIV', i.e. '5 DIV 2.0' gives out
an integer value of 2.
Getting back the Last Calculated Value
The special variable 'ANS' or 'ans' is assigned the value of the last
calculation. If this is an integer, ANS takes an integer value, if
this is a floating value, ANS is floating, otherwise ANS starts with
an integer value of 0. Like any other variable, ANS may be assigned a
value. e.g. let ANS=2.5 , but it will not appear in the list produced
by the LIST instruction (see below).
Declarations
Additionally you may declare variables to be integer or floating
(double precision) using the key words 'INTEGER' or 'DOUBLE'
respectively followed by a comma separated list of variable names of
any type, either integer or float. You may also assign these variable
names by using '='.
e.g.
INTEGER a, b, c=3
or
DOUBLE A%=1.2,D,e=2.71828
You may not concatenate these declarations.
PRIME Keyword
Prime numbers are not divisible by anything other than 1 and themselves.
If a number is not prime, it can be represented as the product of
primes and powers of primes less than itself, called factors. The
number is said to be 'composite'.
'PRIME' or 'prime' followed by any expression will determine if the
integer produced is a prime number. Complains if the number is
fractional. If the number is negative, the sign is removed before
prime determination. If the number is floating point, it is
integerised, but complains if the result would be too large for an
integer. Indicates if the number is zero or +1 or 1 or even. This is
done in integer arithmetic, so !MFCalc may crash if the number is
too large.
Gives the smallest factor if the number is not prime.
e.g. 'PRIME 2^311' will produce the REM '/* 2147483647 is Prime */'.
'PRIME 13*17' will produce the REM '/* 221 is not Prime, Factor 13 */'.
'PRIME' or 'prime' followed by an expression can also be put,
separated by a colon, at the very end of a colonseparated list of
assignments and 'input' statements (see below).
e.g. A 'Mersenne' prime is one of the form '2^n1', so by repeating
the line: 'input a%:prime 2^a%1', using 'Entry Back' and 'Calculate',
you may investigate for what values of a%, 2^a%1 is prime.
Lastly, PRIME sets ANS to the value of the found lowest factor of the
supplied expression, or to the value 1 if the expression is prime. So,
for example, start with the line 'm%=1:ANS=1'. Then repeat the line:
'm%=m%*ANS:PRIME <expression>:/m%', where <expression>: is the
expression you wish to factorise, and continue until you get a prime.
You will then have found all the prime factors of <expression>:.
Getting Rid of all the Variables
The command 'CLEAR' or 'clear' will remove all the variables and start
from scratch again.
Getting Rid of One Variable
The command 'CLEAR' or 'clear' followed by the variable name will cause
the variable to be removed from the list of defined variable names.
e.g. CLEAR a%
A message indicates if the variable name was already undefined.
Checking the Variables Present
The single command 'LIST' or 'list' and clicking 'Calculate' will
cause an alphabetical list of the variable names and values to appear
in the Input Slot. After each line, press the Return (Enter) key and a
new line appears, or a message indicating the end of the list.
Pressing the Escape key at any time terminates the list and a message
indicating that appears. A message also indicates when no variables
have been defined. The list also shows if the variable has not been
explicitly assigned a value. Also the form of representation of the
assigned value in the list gives the variable's data type  it is
represented as an integer without a decimal point if the variable is
to be taken as holding an integer value  with a decimal point if it
is a floating variable e.g. a variable with the a value of six would
be listed with a value '6' if it was an integer variable, but '6.0' if
it was a floating (double precision) variable.
The Field Length and Number of Decimal Places
Just type numeric values into the slots provided, then press
the 'Enter' key (Return). !MFCalc requires that you press 'Enter'
before these values are recognised. Clearing them out to nothing just
leaves the values unaltered. !MFCalc complains if you try to make the
field length less than the number of places, or the number of places
more than the field length. Not available in hexadecimal or octal
notation. Also the choice of representation in floating, exponential
or general format is only available in decimal notation, not hex or
octal.
The INPUT command
The key word 'INPUT' followed by a single variable name e.g. INPUT a%
will cause a prompt REM of the form: '/* Type a%, Enter or Escape */
to appear in the 'Input:' slot together with a red caret. Typing the
value at the caret and pressing 'Enter' ('Return') will assign the
variable a% with the typed literal. Pressing the 'Escape' key at this
point leaves the variable unassigned with its default value of zero.
Note that !MFCalc will only accept literals e.g. 123, 2.31, &123,
&o127, 1E2, 0.5e04 or a single variable name at the prompt, not whole
expressions. The only exception is that you may put a minus '' sign
in front.
Also Note pressing the 'Backspace' or 'Delete' key, if you make a
mistake, will erase the mistaken entry, and assign the variable the
new value on pressing 'Enter' ('Return'). Pressing the 'Escape' key,
as mentioned above, aborts the current INPUT statement. In this case,
no new value is assigned. This is useful if you do not wish to alter
the value of an INPUT variable. If you use the cursor keys to move
backwards and forwards in the 'Input:' slot, they will have no effect.
Inherited Unassignment: If you use INPUT and enter an unassigned
variable name at the prompt, then the INPUT variable remains
unassigned.
INPUT statements can be concatenated, so, you may put e.g.
INPUT a%:INPUT b%:INPUT c%
And !MFCalc will prompt for the value a%, then b%, then c%
The INPUT statement allows you to give your own prompt by supplying a
double quoted character string, which is converted to your own REM before
the prompt caret e.g. 'INPUT "Give Value"; a%' will give:
'/* Give Value */ followed by a prompt for the value. If you
supply '/*' or '*/' in the quoted string, they are removed from the
REM. If you require a double quote, supply "" within the string, which
is converted to a " within your REM. The semicolon afterwards, when
supplied, suppresses a '?' from being added to the REM.
The PRINT Command
'PRINT' followed by any expression simply gives the value of the
expression when the 'Calculate' button is clicked on. The advantage is
that this command can occur after a colon at the end of any series of
assignments or INPUTs e.g.
'INPUT a%:b%=1:INPUT c%:PRINT a%+b%+c%' will prompt for the values of
a% and c% then give the value of a%+b%+c%. PRINT should only occur at
the end of an 'Input:' line.
Similarly to INPUT, PRINT can be followed by a string of characters in
double quotes before the expression. The string will be output as a
comment before the value of the expression when 'Calculate' is clicked
on. You may separate the string from the expression by a semicolon,
but it has no effect.
As described below, you may bring this line back and so perform a
calculation many times over with different input values.
The 'Entry Back' and 'Entry Forward' Buttons
Every time you click on 'Calculate', the 'Input:' slot value is stored
away on a stack. The 'Entry Back' button, when clicked,
successively brings back previous 'Input:' lines into the 'Input:'
slot. There is enough storage to hold up to twenty previous lines.
When this is exceeded, the 'stack' shifts up, so lines more than
twenty ago are lost.
The 'Entry Forward' button moves forward in time right up to the
current line, reversing the effect of 'Entry Back'.
Neither of these buttons have any effect until you have entered
several lines.
If you go back to a previous line, then enter a different line and
click on 'Calculate', then immediately the entries forward in time
from the chosen line are lost, but those previous in time to the
chosen line can still be obtained by clicking on the 'Entry Back'
button.
'Input:' Lines are not recorded in the memory stack if they are blank
or they repeat the same calculation as the previous entry on the
stack. This means you can repeat previous calculations without it
affecting the previous line memory stack.
Lastly, the 'Clear Entries' button completely clears out the memory
stack and all knowledge of any previous lines is lost. Remember to
distinguish this from the 'Clear Entry' button, that just clears out
the 'Input:' slot and has no effect on the memory stack.
The 'Save Entries' and 'Retrieve Entries' Buttons
The 'Save Entries' Button copies all the entries in the memory stack
to an internal file, which can be brought back by clicking on the
'Retrieve Entries' Button, even after you have Quit the whole
application. Both buttons give out a message indicating how many
entries were Saved/Retrieved, but in the case of 'Retrieve Entries',
Press the 'Enter' ('Return') key afterwards. The entry you will then
see in the 'Input:' slot is the last one you were looking at when you
Saved the Entries.
If you have a constant set of calculations you perform, this saves
having to type them in time and again.
Getting Out of the Application
You may select 'Quit' from both the icon bar menu and the 'Help' menu
to terminate the application. Selecting the 'Close' icon on the
'SetUp' panel simply removes the panel and does not clear any of the
variable names, but typing 'QUIT' or 'quit' in the 'Input' slot and
clicking 'Calculate' both removes the panel and clears the variable
names. Lastly, typing 'EXIT' or 'exit' and clicking 'Calculate'
completely terminates the application. In certain circumstances, the
'Escape' key has the same effect as 'QUIT'.
Bugs
1. It has been discovered that the value returned for the Sine of 90
degrees is marginally greater than one, so if you immediately perform
an Arc Sine on this value, !MFCalc objects to the number input to Arc
Sine being greater than one. i.e. ASN SIN 90 in degree mode produces
an error message, not a return value of 90. The same is true of SIN 90.
The same is not true of the COS of zero.
2. If the resulting value of integer arithmetic with '+', '', '*' or
'^' overflows the 32 bits used for its (signed) representation, then
the calculation is converted to a floating one. The same is not true
for floating calculations. If you wish to calculate with large
numbers, then you could use floating arithmetic e.g. represent one
hundred million as '100000000.0'. However, if any integer literal in a
calculation exceeds about 8 digits, it is automatically converted so
as to be taken as floating literal and the whole calculation is
performed as a floating one anyway.
Integer '/', MOD or DIV are calculated in integer storage. If the
numbers involved are large (roughly over 8 digits), it can cause
integer overflow and !MFCalc crashes.
Also realise that even if the calculation is done in floating point
format, because of the way the number is stored, only 16  17
significant digits can be held. If, for example, the result of the
calculation exceeds 10^17, then only the first 16  17 digits will
appear before the decimal point, the rest being zero.
3. For various reasons, it is best to perform repeated raising to
powers (using '^') as all integer as all float (not mixed arithmetic).
e.g. 3 ^ 2 ^ 2 or 3.0 ^ 2.0 ^ 2.0, but not 3 ^ 2.0 ^ 2.0
However, with a single '^', any mixture of integer or float is
acceptable. As mentioned above, if the two operands are integer, the
result is an integer, but otherwise the result is floating.
Also beware of large numeric values (overflow) developing during
repeated exponentiation. It can produce very odd output results,
particularly when displaying in 'Floating' mode.
Reserved Words
A list of the reserved words (both in upper and lower case) used by
!MFCalc follow. They should not be used as variable names. If you get
an odd result or a syntax error, then you are probably using a
reserved word in the wrong place, or think you are using one when
you have typed it incorrectly or not separated it properly from other
alphanumerics. Note the reserved words are either all upper case or
all lower case and not any mixture:
"ABS",
"ACS", "ANS", "ASN", "ATN", "CBR", "CBRT", "CLEAR", "COS", "COSH", "DIV", "DOUBLE", "EXIT", "EXP", "FIX", "FRAC", "GCD", "INPUT", "INT", "INTEGER", "LCM", "LET", "LIST", "LN", "LNFACT", "LOG", "MAX", "MIN", "MOD", "NCR", "PI", "PRIME", "PRINT", "QUIT", "RAND", "REM", "RND", "SGN", "SIN", "SINH", "SQR", "SQRT", "TAN", "TANH", "abs", "acs", "ans", "asn", "atn", "cbr", "cbrt", "clear", "cos", "cosh", "div", "double", "exit", "exp", "fix", "frac", "gcd", "input", "int", "integer", "lcm", "let", "list", "ln", "lnfact", "log", "max", "min", "mod", "ncr", "pi", "prime", "print", "quit", "rand", "rem", "rnd", "sgn", "sin", "sinh", "sqr", "sqrt", "tan", "tanh".
Eighty eight reserved words in all, forty four in lower and forty four in upper case.
Have fun!
Queries, curses, praise to:
Martin Carradus, Leaf Mindcraft, c/o 27 Wells Road, Ilkley, West Yorkshire, LS29 9JE.
Send s.a.e. if you require a reply.
NB. Please read the Text file !ReadMe within this application for conditions of use.
(Hold down 'Shift' and double click with the Mouse over the !MFCalc icon to find it.)
Martin Carradus July 2004.
