UBASIC - Help File

"NOTE: Unless you place statements such as
10 word 30
and
20 point 20
at the beginning of your UBASIC program, you will not get added precision."

Running UBASIC86

Insert the UBASIC86 distribution diskette, then type

UBIBM32<Enter>

(<Enter> is the large key engraved "Enter" or "Return" or a bent arrow.)

To run the example program "PI.UB" on the distribution diskette, type

RUN<Enter>

The program will prompt you to enter how many places you want pi to be displayed (10-2500). Type for example

1000<Enter>

Your screen will display 3.14159... to 1000 decimal places. Type

LIST<Enter>

to examine the program. Finally, type

SYSTEM<Enter>

to exit to the DOS.

NUMBERS

UBASIC86 supports integers, rational numbers, real numbers and complex numbers.

1-1. Integers
UBASIC86 supports a wide range of integers from -65536^540 to 65536^540 which is a number in a little more than 2600 figures in decimal expression. Results outside of this range create an overflow. Hexadecimal integers can be entered as '0x..' (not '&h..').

1-2. Rational numbers
UBASIC86 allows calculations with rational numbers, The type of value is limited to integer / integer. Numerator and denominator are separated by '//'.
Ex: a=2//3

a=3:b=5:c=a//b

Expressions may differ from the input, as rational numbers are memorized as an irreducible fraction.

Since // has the same precedence as *, /, \, or @, the order of operations may not be the same as you expected. Use parentheses to avoid this.
Ex: 2\6//3 = 0

2\(6//3) = 1

When a rational number is mixed with real or complex numbers, it is automatically converted to a real. This also happens when it is the real part or the imaginary part of a complex number.

Rational arguments are automatically converted to reals in functions like SIN, EXP, etc.

1-3. Real numbers
Real numbers are expressed as fixed point numbers. The maximum amount of memory occupied by the integer part and the decimal part is fixed at 540 words. The size of the decimal part is specified by the POINT statement. The default value is 4, that is, 4 words are assigned to the decimal part and 536 words to the integer part. The smallest positive real number is 65536^(-4), since 1 word is 65536.

1-4. Complex numbers
UBASIC86 allows calculations with complex numbers as well as with real numbers. The maximum size allowed in a complex number is 540 words including both the real part and the imaginary part.

As the real part is usually about as large as the imaginary part, the maximum size of each part is 270 words, that is, 1300 digits in decimal notation.

Read the following examples carefully, since the expression of complex numbers in UBASIC86 is a little peculiar.

The imaginary unit is represented by "#i". Complex numbers are expressed as follows:-

```>
numbers		1+#i, 1.23+2.34#i, 12345+23456.789#i
* is not necessary.
1.23+#i*2.34, 12345+#i*23456.789
* is necessary.
variables, etc.	A+B*#i, Abc+#i*sin(x)
* is necessary.
```
Notes: 1/2#i is interpreted as 1/(2#i). So the result is -0.5#i. 1/2*#i is interpreted as (1/2)*#i. So the result is 0.5#i. Similarly, 2^3#i is 2^(3#i) while 2^3*#i is (2^3)*#i.

When complex numbers are used, set the WORD value to more than 4 * POINT(for example, if POINT = 10, then WORD must be more than 40). Otherwise, overflow can easily occur for reasons of internal structure when a complex number is assigned to a long variable.

There are 3 functions that return absolute values: ABS, ABSMAX, ABSADD.

abs(z) = sqrt(Re(z)^2+Im(z)^2)
absmax(z) = max{abs(Re(z)),abs(Im(z))}

ABS returns the ordinary absolute value, but it takes more time. ABSMAX and ABSADD are recommended to check errors quickly.

ARG(x) returns the argument of x. The value returned is A, where -pi < A <= pi.

UBASIC86 has the complex number versions of the following functions: EXP, LOG, SIN, COS, TAN, ATAN, SINH, COSH, SQRT, BESSELI, BESSELJ.

<< Notes for mixed types expressions >> Different types of numbers can be used together in one expression. Result type may vary with the order of the operations.

Ex: 1.0+1-1.0 = 1.0 (real)

1.0-1.0+1 = 1 (integer)

This is because when a result of the calculation of reals and/or complex numbers is 0, it is converted to an integer.

There are round-off errors caused by conversions from internal binary expression to decimal output. These errors are typically seen in the expressions of '0'. If the output is '0' it really is '0', while '0.0' and '-0.0' are nonzero values that are too small to be expressed. Note that this occurs only for 0. '1.0' may be equal to '1' or a little larger or smaller. To know which, subtract 1 from it. As a result of calculation, there is no essential difference between '1'(integer) and exact '1.0' (real), though the size of the internal memory required is different. Naturally, '1' (integer) needs less memory and can be calculated faster.

VARIABLES

UBASIC86 has three types of variables:

1. Short variables, such as A%, Foo_bar% (and arrays) A short variable holds a one-word (16-bit) integer (-32767, ..., 32767). Rational numbers, complex numbers, and strings cannot be assigned to a short variable.

2. Long variables, such as A, Foo_bar (and arrays) The size of long variables is specified by WORD statement. It cannot be specified individually.

3. EXTRA variables, such as A#, Foo_bar# (and arrays) Variables whose size is fixed at 540 words.
A variable name is a letter, possibly followed by at most 15 letters, digits, and underscores(_). Short and EXTRA variable names have a final "%" and "#" character, respectively. A variable name may not coincide with UBASIC86 statements/ functions and it may not start with "fn" (which is the mark of user defined functions).

The first character is automatically converted to uppercase while the rest is left as is. Uppercase and lowercase letters are not distinguished.

```Ex:	A, BC, MaximumElement, Maxscore%, Minscore(10)
Abcdefghi and ABCDEFGHI are regarded as the same.
NextOne, Step1, etc. are distinguished from  the
statements NEXT, STEP, etc.
```
A simple variable and an array with the same name are distinguished.

Arrays of up to three dimensions may be declared. Array indices may be as large as 65534. So the size of a one- dimensional array of short variables is up to 128 KB. The size of an array of two dimensions can be as large as the available memory.

There is no need of EXTRA variables if the length of long variables is specified as 540 words. EXTRA variables are used when a few large numbers occur among many relatively short long variables.

Long variables and EXTRA variables can be assigned integers, rationals, reals, complex numbers, character strings and polynomials.

See appendix A for the internal expressions of numbers, strings and polynomials.

An overflow occurs when the length of variable exceeds 540 words in the process of calculation, or when a result exceeding the limit of the variable is assigned. In particular, in multiplication and division of real numbers, the intermediate results very often exceed 540 words. This is because UBASIC86 executes the operation using all the significant figures and discards the less significant ones afterwards.

No more than 180 variables and arrays may be used simultaneously.

OPERATIONS

3-1. Operators

```  Logical Or			or
Logical And			and
Comparisons			=, >, <, <>, <=, >=
Multiplication, Division	*, /
Integer Division		\
Rational Division		//
Remainder			@
Power				^
```
3-2. Value of logical expression
In UBASIC86, the value of logical expression is 1 when it is TRUE 0 when it is FALSE. In conditional expressions, a nonzero value is regarded as TRUE. So:-
if A<>0 then ...
is equivalent to:
if A then ...

This is valid also when A contains a real number. However, this short form is not recommended.

3-3. Division of real numbers (/) and integers (\)

Usual division is calculated up to the decimal place specified by POINT. The digits past that place are omitted. Integer division returns an integer quotient when both of the arguments are integers. A real or complex argument creates an error.

The remainder of an integer division is contained by the system variable RES while remainder of a real division is undefined.
Ex: 12345/100 is 123.45 (actually 123.449999...)

12345\100 is 123. Remainder is 45.

If the remainder is 0, the result varies with "/" and "\".
Ex: 123/3 is 41.0, while 123\3 is 41.

In the process of integer division A\B, the quotient is determined in such a way that the remainder is non-negative and numerically less than ABS(B).

This seems natural in division by positive numbers, but rather strange if a negative divisor is involved. For instance, (-1)/100 is -1 and the remainder is 99. So -1 never becomes 0 by repeated integer division. Take care when you check the conclusion of a loop.

3-4. Division of rational numbers (//)

Division of rationals returns a rational when both of the arguments are rationals. Otherwise, it is the same as real division (/).
Ex: (2//3)//3 is 2//9

(2//3)/3 is 0.2222...
0.5//2 is 0.25

3-5. Calculation of a remainder

@ is the remainder of integer division.

It is different from MOD in some languages since it is determined as above (Section 3-3.) if a negative number is involved.

The remainder of

integer \ integer
complex number with integer coefficient \ integer
polynomial \ polynomial
just calculated is held by the system variable RES so that you do not need to use @. @ is used when only the remainder is needed and the quotient is not needed.

Note that the value of RES must be used just after the calculation, as it is destroyed by other calculations.

3-6. Power X^Y.

Powers of integers, reals, complex numbers, rationals, and polynomials.

• If Y is positive, the result is X to the Y .
• The return value is exact if X is an integer, while it is an approximate value if X is a real.
• If Y is 0, the result is 1 as a polynomial of degree 0 when X is a polynomial, otherwise 1 as an integer regardless of the type of X. 0^0 is 1.
• If Y is not zero and X is zero, the result is 0.
• See appendix B for the algorithm in the case where Y is a real or a complex number.
• X^Y^Z is usually interpreted as X^(Y^Z), but it is (X^Y)^Z in UBASIC86.

3-7. Combined operators

Combined operators are borrowed from the C language.

A+=B is equivalent to A=A+B.

This can save you the trouble of typing long variable names. Use of the combined operator can also speed up a program, since the calculation of the internal address of an array is executed only once. The right hand side is evaluated before the combined operation:-

A*=B+C means A=A*(B+C), not A=A*B+C.

CHARACTER STRINGS

Like ordinary BASIC, UBASIC86 allows character strings. However, UBASIC86 has no string variables. Use long variables or extra variables to assign character strings. Since one character occupies 1 byte, a variable can contain twice as many characters as the WORD value: for example, 20 characters when the WORD value is 10.

Character strings are compared by ASCII code in lexicographic order.

POLYNOMIALS

UBASIC86 allows polynomials in one variable.
There are two types of polynomials: polynomials with coefficients in integers modulo a prime (<= 65536) (we call them "modulo polynomials"), and normal polynomials. In the former type we can handle polynomials up to about the 1000th degree, but in the latter type we can handle only polynomials of relatively lower degree (e.g. up to (1+X)^95).

5-1. Entering of polynomials

The variable of a polynomial is represented by "_X".

Ex: A=1+2*_X+3*_X^2

However, the result is displayed with "X".
Ex: A=1+2*_X+3*_X^2:print A

displays "3*X^2 + 2*X + 1".

You may also use the function POLY to specify the coefficients in order starting with the coefficient of degree 0.
Ex: A=poly(1,2,3) is equivalent to the above example.

To specify the coefficient of each degree, use COEFF.
Ex: A=0:coeff(A,0)=1:coeff(A,1)=2:coeff(A,2)=3

is equivalent to the above examples.

Note that the variables specified by COEFF have to contain a polynomial (or 0). The value of the system variable MODULUS determines whether a polynomial is a modulo polynomial or a normal one. If MODULUS is 0, it is a normal one and if MODULUS is a prime, it is a modulo polynomial.

5-2. Calculation with polynomials

The following calculation are allowed with polynomials:

```	Addition	+
Subtraction	-
Multiplication  *
Division	\
Remainder	@
Power		^
Differential	diff
Value ( A(Y) )  val(A,Y)
```
Note that the division is "\".

The system variable RES contains the remainder after the division of polynomials.

Calculations with a normal polynomial and a modulo polynomial are not allowed. Calculations with modulo polynomials create an error if the value of MODULUS is not as it was when the polynomials were entered. In particular, calculations containing polynomials created under different values of MODULUS are not allowed. VAL returns the value of the polynomial as evaluated for the given n.
Ex: A=poly(1,1):print val(A,2)

displays "3". (when MODULUS=0)

A number and a polynomial of degree 0 are distinguished in the following cases:

```polynomial / number
Each coefficient / number.
polynomial / polynomial of degree 0
Error.
polynomial \ number
Each coefficient \ number.
The value of RES is not valid.
polynomial \ polynomial
of degree 0
Division of polynomials.
polynomial @ number
Each coefficient @ number.
The value of RES is not valid.
polynomial @ polynomial of degree 0
Remainder of division of polynomials.
polynomial // number
Each coefficient // number.
polynomial // polynomial of degree 0
Error.
```
Ex: When A=_X^2+2*_X+3,
A\2 is _X+1 and the value of RES is not valid.
A\poly(2) is (1//2)*_X^2+_X+(3//2) and the remainder is 0.
```modulo polynomial / number
Each coefficient * inverse of number.
modulo polynomial / polynomial of degree 0
Error.
modulo polynomial \ number
Error.
modulo polynomial \ polynomial of degree 0
Division of modulo polynomials.
modulo polynomial @ number
Error.
modulo polynomial @ polynomial of degree 0
Remainder of division of polynomials.
modulo polynomial // number
Same as modulo polynomial / number.
modulo polynomial // polynomial of degree 0
Error.
```

PACKETS

Sometimes you may prefer to handle multiple data as one. UBASIC86 allows assigning multiple values to one variable. We call this "a packet" (this is usually called "a list", but UBASIC86's "list" is too poor to call "a list").

It is recommended to assign a packet to an EXTRA variable so that the limit of its length is not modified by the WORD statement. A long variable can be used if the WORD value is correctly set.

A#=pack(23,"abc",1+3#i)
assigns an integer 23, a string "abc" and a complex number 1+3#i to A#.

To know the number of members PACKed in a packet, use LEN.

When A#=pack(23,"abc",1+3#i), len(A#) is 3.

To get a PACKed member, use MEMBER.

When A#=pack(23,"abc",1+3#i), member(A#,1) is 23.

Use MEMBER also to replace specified data.

member(A#,3)="abc"
replaces the third member 1+3#i with a character string "abc".

A packet can be edited using LEFT, RIGHT, MID as well as a character string. Consider 1 member as 1 character. Note that the return value in this case is a packet.
Ex: left(pack(2,4,6),1) is pack(2),

not 2 itself. To get 2 itself, use MEMBER mentioned above.

To add data to a packet, use "+".

A#=A#+1000
or
A#+=1000
adds a new member 1000 to A#. "+" is used also to join 2 packets.

The word length required by a packet is the sum of the word length of all the member + 1.

In the case of A#=pack(23,"abc",1+3#i),

```Integer 23:		data 1 word + attribute 1 word
String "abc":		data 1 word + attribute 1 word
Real part of complex number 1+3#i:
data 1 word + attribute 1 word
Imaginary part of complex number 1+3#i:
data 1 word + attribute 1 word
Complex number 1+3#i:	attribute 1 word
Number of members (3 in this case):
1 word
Total:			11 words
```
(Actually, "attribute 1 word" of the packet itself is required.)

So if a WORD value larger than 11 is specified, the packet can be assigned to a long variable.

LABELS

"Label" is a name given to the destination of GOTO and GOSUB.
It is recommended that labels be used instead of line numbers whenever convenient.

The following two examples are equivalent:

```....			....
110 gosub 1000		110 gosub *ABCD
....			....
1000 ....		1000 *ABCD:....
....			....
1100 return		1100 return
```
A label is a * followed by no more than 23 characters (letters, digits, ".", "_" and "?"). Upper and lower case are not distinguished.

Labels (such as *ABCD on line 1000 in the example above) must head their lines. At most 100 labels may be used; the use of many labels slows the execution down.

The RUN statement forms the list of labels. So if the program is executed by GOTO, the results are unpredictable.

KEYS

1. The function of special keys

```Delete		Deletes the character under the cursor.
Backspace	Deletes the character to the left of the
cursor.
Insert		Toggles insert mode on/off.  A box
cursor is displayed in insert mode.

Home		Moves the cursor to the home position

Esc		Cancels the listing of file choices in
commands such as LOAD, RUN, etc.

Arrow keys	Move cursor

2. Editing Control Keys

"Control-X" means to hit "X" while pressing the control key
at the left end of the keyboard.
Control-E:  Cursor up
Control-X:  Cursor down
Control-S:  Cursor left
Control-D:  Cursor right

Control-Z:  Scroll up
Control-W:  Scroll down

Control-R:  Page down
Control-C:  Page up

Control-A:  Cursor leftmost(=Home)
Control-F:  Cursor rightmost(=End)
Control-Q:  Cursor leftmost(=Home)

Control-L:  Clear the screen
Control-B:  Delete lines below cursor
Control-Y:  Delete right of cursor
Control-G:  Delete character at cursor (=Delete)
Control-H:  Delete character left of cursor (=Backspace)
Control-O:  Insert a line

Control-V:  Insert/Overwrite toggle(=Insert)
Box cursor is displayed in the insert mode.

Control-C:  Halt execution, LIST, VXREF, etc.
(Control-BREAK is recommended)
Control-S:  Halt/Restart display

Control-BREAK: Halt execution. More sensitive than CTRL-C.

Control-N: In some versions of MS-DOS, this means "printer line
feed" and in some cases, (especially when the printer is ON and
off-line) the execution is halted and key inputs are not
accepted.  To cancel this, turn off the printer or make it
on-line.

3. Function Keys

You may modify the settings of function keys using KEY.
Default settings are as follows:

f1	load "		f6	save "
f2	dir "*.UB"	f7	xref
f3	auto		f8	append "
f4	list		f9	edit
f5	run		f10	cont

SUBROUTINES AND FUNCTIONS

The biggest defect of normal BASIC is the difficulty of
making a program independent.  For example, if you are going
to use a FOR-NEXT loop in a subroutine, you may find it
difficult to choose the name of the loop variable.
Because of this problem, it is almost impossible to make a
useful program into a module.  UBASIC86 offers some ways to
solve this problem.

Passing Arguments

Arguments can be passed to subroutines.
10	A=1:B=2:C=0
20	gosub *MAX(A,B,&C)
30	print C
40	end
100	*MAX(X,Y,&Z)
110	  if X>=Y then Z=X else Z=Y
120	return

At the beginning of the subroutine MAX, the values of
variables A and B are passed to the different variables X and
Y (call by value).  As X and Y are variables valid only in the
subroutine MAX (local variables), changing of their values
does not affect the main routine.  The variable C with "&" is
regarded as the same as Z in the subroutine MAX (call by
reference).  So if you change the value of Z in the subroutine
MAX, the value of C also changes so that you can return the
result to the main routine.  This condition is initialized by
the RETURN in line 120.

The format is different from those in Quick BASIC and Visual
BASIC.

Limitations:
A simple short variable cannot be passed by reference.
That is, gosub *ABC(&A%) is not allowed.
A member of an array cannot be passed by reference.
That is, gosub *ABC(&A(1)) is not allowed.

User defined functions

A function that extends to multiple lines can be defined.
10	A=1:B=2
20	C=fnMAX(A,B)
30	print C
40	end
100	fnMAX(X,Y)
110	  if X
As above, "fn" is required before the function name.  The
return value of the function is placed between "()" after
"return".  The return value can be an expression.  In the above
example, the function changes the value of X.  Note that this
does not affect the main routine.

You may call functions and subroutines LOADed into memory in
direct mode without RUNning the program.  For example, if you
LOAD the program "GENSHI" and type "? .genshi(13)", "2" is
displayed ("?" and "." are abbreviations of "print" and "fn"
respectively.)

So if you collect frequently used subroutines/functions and
make them into one program, you have only to LOAD it to use
the subroutines/functions as you like in direct mode.  This
will serve you as an electronic calculator.

A user defined function itself can be passed to subroutine/
function as an argument.  See the "Guide" or the sample program
"Simpson" for an example.

From version 8.82, the classical one line function definition
is available.
10	A=1:B=2:C=3
20	def fnA(X,Y,Z)=X+Y-Z
30	print fnA(A,B,C)

Local Variables

Local variables are variables valid only in a subroutine/
function.
10	for I=1 to 10
20	  gosub *ABC(I)
30	next
40	end
100	*ABC(X)
110	  local I
120	  for I=1 to X
130	    print X;
140	  next
150	  print
160	return

I is declared as a local variable in line 110.  This I is
distinguished from I in the main routine until RETURN.  The
value is initialized to 0 by the LOCAL declaration.  The
arguments of a subroutine/function mentioned above are also
regarded as local variables.

The beginning of a subroutine/function must be in the
following format:
Declaration of the subroutine/function.
Declarations of local variables beginning with LOCAL.
(Multiple lines are allowed.)
Declarations of local arrays beginning with DIM.
(Multiple lines are allowed.)

The latter two may be placed in reverse order or
alternately.  Other statements other than comments are not
allowed in the middle of these declarations.

Limitations:
The maximum depth of recursive calls is up to 40.
Local labels are not available.  So when several
user defined functions are APPENDed, an error occurs
if these functions have the same label.

EMA-array

Expanded Memory usable for optional Arrays.

Their names are ema(0;i,j), ema(1;i,j),..., ema(15;i,j) only.
0; can be omitted.

Limitation:
1 or 2 dimensional.
cannot be passed to subroutines as parameters.
cannot be preserved by freeze command.
cannot be erased.
cannot be handled by vlist, vxref, vchg.
each index must be less than 2^32-1.
(from v8.24 : CAN be declared as local variables.)
(from v8.77 : range of indices are extended to 2^32-1)

1) Install the Expanded Memory Manager(satisfying LIM-EMS4.0)
Usually add a line like :
device = c:\dos\emm.sys
or
device = c:\dos\emm386.exe 4096 frame=e000 ram
to the config.sys file.

2) Decide the size of an element.
Default size is same as that of long variables.
To change the size do:
emaword 100
each element of EMA is 100 words long.

3) Decide the size of an array
dim ema(0;9,99)
2 dimensional, 1st indices are from 0 to 9, 2nd indices
are from 0 to 99.

Sample:
10	emaword 10
30	dim ema(0;N-1,N-1)
40	dim ema(1;N-1,N-1)
70	data 3
80	data 1,2,3,4,5,6,7,8,9
90	data 3,4,5,6,7,2,3,4,5
100	'
110	gosub *DispEma(0):print
120	gosub *DispEma(1):print
140	gosub *DispEma(0)
150	end
160	'
180	  local I,J
190	  for I=0 to N-1
200	    for J=0 to N-1
220	    next
230	  next
240	return
250	'
270	  local I,J
280	  for I=0 to N-1
290	    for J=0 to N-1
300	      ema(A;I,J)+=ema(B;I,J)
310	    next
320	  next
330	return
340	'
350	*DispEma(A)
360	  local I,J
370	  for I=0 to N-1
380	    for J=0 to N-1
390	      print ema(A;I,J);
400	    next:print
410	  next
420	return

Note:	Some of block commands are usable:
Ex:	block ema(0;1,*)=123
block ema(0;*,*)+=block ema(1;*,*)
clr, neg, swap block ema( ) are also usable.

Note:	We recommend you to use normal arrays at first and
compute for small parameters.  After debugging the
program, you save the program in the ASCII mode(use
asave) and replace the names of normal arrays by
And then enlarge the size of parameters.  We think
you will be confused if you will use EMA-arrays from
the beginning.

Random Files

Disk files are usable for optional arrays.  Their names are
file1, file2, file3 only.

Limitation:
1 or 2 dimensional(2 dimensional is available from v8.87).

1) make a new file
open "ABC" for create as file1(1000) word 100
uses file "ABC" for the array named file1.  The indices are
from 0 to 1000.  Size of each element is 100 words.

file1(10)=123
print file1(5)

3) close file
close file1

4) use again
open "ABC" as file1

Sample:
10	'GENWRITE version 2.0
20	open "GENTBL" for create as file1(6542) word 1
30	file1(0)=0:file1(1)=1
40	for I=2 to 6542
50	  print I,
60	  P=prm(I)
70	  file1(I)=fnGenshi(P)
80	next
90	end
100	'
110	fnGenshi(P)
120	  local Gen=1,N=P-1,Nw,Div,Sw%
130	  if P=2 then return(1)
140	  if or{P<3,len(P)>32,prmdiv(P)

User Program

Machine language programs can be put in predeclared arrays of
Short variables and called by array names.  The program starts
at 0100H on the array's segment.  It must be of .COM type with
extension .UBB. (Note: EXE2BIN was distributed with older DOS
and hard to get now.)
Arguments are passed via either variables or the first 28
elements of the array.  The memory map, after the
is as follows:

0000H-001FH	Size of the array etc.  Do not rewrite this
area.
0020H-003FH	0th through 15th elements of an array, which
can be used to pass arguments.
0040H-0041H	Byte size of Long Variables
((value specified by WORD) * 2 + 2)
0042H-0043H	Byte size of EXTRA Variables
0044H-0045H	Offset of the work area that holds the current
position of the calculation stack.  Segment is
SS.
0046H-0047H	Segment of system constant area.
0080H-00FFH	Offset and segment of 1st argument, offset and
segment of 2nd argument, ...(addresses of at
most 32 arguments, each 4 bytes long)

The segment:offset pairs for the arguments may be omitted if
the values are unchanged.  If you omit them, either use empty
parentheses or successive commas.  When the routine is called,
the registers are such that DS = ES = SS <> CS.  Use far
returns.  Do not change DS, ES, SS, BP, and the string
direction flag.

Ex1:

This example clears the 0th through 9th elements of an array.
The program name is CLR10, say.  The main program contains the
three lines,

DIM CL%(150)
CALL CL%(X%(0))

When the user program is called, the address of the 0th element
of the array is in CS:0080H.  The source program would be as
follows.  MAKEUBB CLR10 makes an executable program.

;SAMPLE FOR MAKING USER PROGRAM
CODE	SEGMENT
ASSUME  CS:CODE,DS:CODE

ORG	100H
START:

CLR10	PROC	FAR		;make it a PROC FAR to generate
;RETF code
MOV	BX,80H
LES	DI,CS:[BX]	;get segment:offset of 0th
;element of the array
MOV	CX,10
XOR	AX,AX
REP	STOSW
MOV	AX,SS		;recover DS,ES,BP.
MOV	ES,AX		;DS,ES may be set equal to SS
RET

CLR10	ENDP

CODE	ENDS
END	START

Ex2:

To call UBASIC86's calculation routine from user programs,
put necessary arguments onto the calculation stack; see UB.MAC
macro definition file.

PUSH(@PUSH) and POP(@POP) do not allow Short Variables.

For the example let's make a program doing:
"For the variables A, B, C, calculate C=A+B or C=A-B
according to the 0-th element of the array."

UBASIC86 program is:

20   'sample for machine language program
30   '
40   dim AddSub%(200)	reserve user program area
load user program and set parameters
60   A=123:B=234
70   AddSub%(0)=0		store a value to 0-array element
80   call AddSub%()		call user program
90   print A,B,C
120   print A,B,C
130   end

Assembly program is:

include	UB.MAC		read macro definition file

mov	bx,AR0
mov	ax,cs:[bx]	get the value of 0-th element
cmp	ax,1
je	subAB
hlt

@push	v1	push 1st parameter to calc_stack
@push	v2	     2nd
getC:
@pop	v3	send the result to 3rd parameter
mov	ax,ss
mov	ds,ax
mov	es,ax
retf

subAB:
@push	v1
@push	v2
@sub
jmp	getC

code	ends
end	start

"makeubb addsub" will translate this assembly program to
object program.  MASM and LINK are needed.  For other
assemblers and linkers, rewrite the makeubb.bat file.

Output Redirection

Output of PRINT/LPRINT statements can be redirected and
pluralized.

Ex:	PRINT = PRINT + LPRINT + "ABC".

This makes PRINT statements to output to the screen,
printer, and file "ABC" until another such command or NEW or
LOAD is executed.  The PRINT#1 outputs are binary whereas the
command above outputs to "ABC" in the text (ASCII) mode.  Use
SPC or TAB rather than LOCATE and LLOCATE when redirecting to
files.
The right-hand sides of "PRINT =" and "LPRINT =" must be
distinct.

Automatic Execution

To automatically LOAD ECMX and factorize 3^33 + 1 and 6^66 + 1,
make the file "TEST":

PRINT=PRINT+"MEMO"
RUN
3^33+1
6^66+1
0
SYSTEM

Then type UBIBM TEST1.

ASCII <-> BINARY data conversion
ASCII <-> BINARY data conversion

ASCII from/to BINARY data conversion is done by input/output
redirection.

ABC(=BINARY) -> XYZ(=ASCII)
10	open"ABC" for input as #1
20	print=print+"XYZ"
30	while not eof(1)
40	  input #1,A
50	  print A
60	wend
70	close #1
80	print=print
90	end

XYZ(=ASCII) -> ABC(=BINARY)
10	open"ABC" for output as #1
20	input="XYZ"
30	loop
40	  input A
50	  print #1,A
60	endloop
This stops at the line 40 when this encounters the file end.
But don't care.

Type:
close #1:input=input:end
to finish the conversion safely.

Graphics

Standard graphic commands are supported.  Please refer to the
sample programs if the documentation is incomplete.

Commands and functions:
----------------------
circle, line, paint, pset, roll
color, gcolor
dot
get, put
gposx, gposy
gprint, gsize, glocate
screen
view, window
mapx, mapy
copy

There are 3 types of coordinates of graphic screen.
(1) The original coordinate is a native coordinate from
(0,0)-(639,479) or (0,0)-(799,599).
(2) The screen coordinate is a simple translation of the original
coordinate so that the upper left corner of the view area is (0,0).
(3) The world coordinate depends on both view and window commands.

Lesson
------
To draw a graph of a function, do as follows:

(1) First set color mode. 23 means 640*480 16colors mode.

10   'gsample
20   screen 23

(2) Before writing strings on the graphic plane, initialize the size
and color and clear the screen.

30   gsize:gcolor -7
40   cls 3

(4) Set a function.

50   F#="X*sin(X)"

(5) Decide the range.

60   Vxh=560:Vx1=320-Vxh\2:Vx2=Vx1+Vxh
70   Vyh=400:Vy1=240-Vyh\2:Vy2=Vy1+Vyh

(6) Display the definition of a function.

80   glocate Vx1,Vy1-18:gprint F#;

(7) Set view port and window.

90   view (Vx1,Vy1)-(Vx2,Vy2),0,7
100   X1=-6*#pi:X2=6*#pi
110   Y1=-6*#pi:Y2=6*#pi
120   window (X1,Y2)-(X2,Y1)

(8) Draw X- and Y- axes.

130   line (X1,0)-(X2,0),1
140   line (0,Y1)-(0,Y2),1

(9) Write scales.

150   glocate mapx(X1)+4,mapy(0):gprint using(3,1),X1;
160   glocate mapx(X2)-44,mapy(0):gprint using(3,1),X2;
170   glocate mapx(0),mapy(Y1)-20:gprint using(3,1),Y1;
180   glocate mapx(0),mapy(Y2)+4:gprint using(3,1),Y2;
190   glocate mapx(0)+4,mapy(0)+4:gprint "0";

(10) Calculate the step of increment of X.

200   Unit=(X2-X1)/Vxh

(11) Convert the code of the function from string to the
internal code.

210   F#=encode(F#)

(12) Set the start point.

220   X=X1
230   pset (X,val(F#)),4

(13) Repeat drawing.

240   for I=1 to Vxh
250      X=X+Unit
260      line -(X,val(F#)),2
270   next
280   end

Note:
CONSOLE has no side effect.

!(n)
See:	Factorial.

_X
Represents the variable when a polynomial is entered.
This is used to distinguish a polynomial from other
expressions.
Ex:	1+2*_X+3*_X^2

The following piece of code will convert a polynomial
entered using "X" to the necessary form using "_X" in
a program in which a polynomial is to be entered:

100	X=_X
110	input "f(x)=";W#

#DOWN

The key code of cursor_move_DOWN.
Out:	integer.
Warning: It's not a character code.

#E
The base of natural logarithms, #e = exp(1).
The precision is specified by the POINT command and is
no more than 540 words.
Assign it to a variable, rather than evaluating it many
times.
Out:	real.
Ex:	print #E    result: 2.7182...

#EPS
The smallest positive number that can be represented
under the current POINT setting.  Use 10 or more
times #eps for the convergence limit of Newton's
method.
Out:	real.

#EULER
Euler's constant, #euler = 0.5772...
Out:	real.

#LEFT
The key code of cursor_move_LEFT.
Out:	integer.
Warning: It's not a character code.

#PI
#pi = 3.14....
The precision is specified by the POINT command and is
no more than 540 words.  Assign it to a variable,
rather than 	evaluating it many times.
Note:	Use PI(x) to get a multiple of #PI.
See:	PI.

#RIGHT
The key code of cursor_move_RIGHT.
Out:	integer.
Warning: It's not a character code.

#SYS(x)
System type of UBASIC86.
Inp:	integer(0,1,2).
Out:	#sys(0) is a country code.
(ex. 1 for USA, 33 for France, 81 for Japan,...)
#sys(1) is a machine type.
0: reserved
1: IBM-PC/AT and compatibles
2: NEC PC-9801
3: NEC PC-H98
4: Fujitsu FM-R
5: Toshiba J-3100
6: AX
7: DOS/V
#sys(2) is a number of bits of CPU calculation unit.
16: UBIBM
32: UBIBM32

#UP
The key code of cursor_move_UP.
Out:	integer.
Warning: It's not a character code.

ABS(x)
Absolute value of x.
Inp:	number.
Out:	integer, rational, real.
Ex:	print abs(1+2#i)    result: 2.2360...

ABS(x)
abs(Re(x)) + abs(Im(x)).
Inp:	number.
Out:	integer, rational, real.

ABSMAX(x)
max{abs(Re(x)), abs(Im(x))}.
Inp:	number.
Out:	integer, rational, real.
Ex:	print absmax(1+2#i)    result: 2

ACOS(x)
ArcCosine of x.
Inp:	real number(-1<=x<=1).
Out:	real number.
Ex:	print acos(0.123)    result: 1.4474...
See:	COS, ASIN, ATAN.

ALEN(x)
Number of decimal digits in the integer part of abs(x).
Note:	Use it with LOCATE, SPC, TAB to format output.
Inp:	integer.
Out:	integer.
Ex:	alen(0) = alen(9) = 1,  alen(-123/10) = 2.

AND
expression1 AND expression2
Logical product.
1 if both arguments are nonzero, 0 otherwise.
Inp:	expressions.
Out:	integer(0 or 1).
Ex:	if A and B then
Note:	Both expressions are evaluated.

AND{expression1,expression2, ...}
Logical product.
1 if all the arguments are nonzero, 0 otherwise.
Inp:	expressions.
Out:	integer(0 or 1).
Ex:	if and{A,B,...} then
When the part between {} is long, use ':' like this:
if and{A,
:B,
:...}
:then
Note:	If one of the argument is zero, it returns 0 at once
without evaluating the following expressions.

APPEND "program_name"
Reads a program and appends it at the end of the
current program.  The appended program is automatically
renumbered.
You cannot insert a program in the middle of the
current program.
A list of programs is displayed if no program name is
given. 	Choose a program with the arrow keys and
<Enter>.
See:	LOAD, SAVE, VCHG, VLIST, VXREF.

Ex:	open "file_name" for APPEND as #n
See:	OPEN.

ARG(x)
Argument of x.
Inp:	number.
Out:	real y (-pi < y <= pi).
Ex:	print arg(1+2#i)    result: 1.1071...

AS
See:	OPEN.

ASAVE "filename"
Saves the current program on to a disk in the standard
DOS text-file form(=ASCII form).
Note:	A program in ASCII form can be exchanged between UBASIC86
and your favorite editor which is more convenient for
writing a large program.
As intermediate code may vary with versions, ASCII form
is recommended if you want to keep a program for a long
time.
If no file name is given(only "), the current day and time
are used as the program name.
See:	SAVE.

ASC(character/string )
ASCII code of a character/string.
Note:	Conversion from internal code(s) of a character/string
to a value.
It is the same as in BASIC if the argument is one
character.
Out:	integer.
Ex:	print asc("A")    result: 65
See:	CHR.

ASIN(x)
ArcSine of x.
Inp:	real number(-1<=x<=1).
Out:	real number.
Ex:	print asin(0.123)    result: 0.1233...
See:	SIN, ACOS, ATAN.

ATAN(x)
Arctangent of x.
If x is real, the value is larger than -pi/2 and less
than or equal to pi/2.
Out:	real, complex number.
Ex:	print atan(1)    result: 0.7853...
See:	TAN, ACOS, ASIN.
appendix B for the algorithm.

ATTRIB(x)
Attribute word of x.
Note:	In ordinary cases, TYPE is recommended.
Inp:	any data.
Out:	string (hexadecimal conversion of the
attribute word).
See:	TYPE. AppendixA

AUTO [start_line_number]
Generates line numbers.
Note:	Starts from largest_line_number+10 if no line number is
given.

BEEP [0 or 1]
'beep' rings the bell for about 1 second. 'beep 1'
starts ringing and 'beep 0' stops it.
Ex:	beep 1:pause 20:beep 0	result: rings the bell for

BESSELI(k,x)
k-th Bessel_I function of x.
Inp:	k is an integer larger than 0. x is a number.
Out:	number.
Ex:	print besseli(1,2.3)    result: 2.0978...
See:	appendix B for the algorithm.

BESSELJ(k,x)
k-th Bessel_J function of x.
Inp:	k is an integer larger than 0. x is a number.
Out:	number.
Ex:	print besselj(1,2.3)    result: 0.5398...
See:	appendix B for the algorithm.

BIT(n,x)
n-th bit of x.
Inp:	n is an integer. x is any data.
Out:	integer (0 or 1).
Ex:	BIT(0, 5) = 1, BIT(1, 5) = 0, BIT(2, 5) = 1,
BIT(3, 5) = 0.
Note:	Result has almost no meaning when x is a decimal.
See:	BITAND, BITCOUNT, BITOR, BITRESET, BITREVERSE,
BITSET, BITXOR, LEN, SFT.

BITAND(x,y)
bitwise logical-AND of x and y.
Inp:	integers (>= 0).
Out:	integer.
Ex:	BITAND(3, 5) = (0011B and 0101B = 0001B) = 1.
See:	BIT, BITCOUNT, BITOR, BITRESET, BITREVERSE, BITSET,
BITXOR, LEN, SFT.

BITCOUNT(x)
number of 1's in the bit pattern of x.
Inp:	integer (>= 0).
Out:	integer.
Ex:	BITCOUNT(5) = 2
See:	BIT, BITAND, BITOR, BITRESET, BITREVERSE, BITSET,
BITXOR, LEN, SFT.

BITOR(x,y)
bitwise logical-OR of x and y.
Inp:	integers (>= 0).
Out:	integer.
Ex:	BITOR(3, 5) = (0011B or 0101B = 0111B) = 7.
See:	BIT, BITAND, BITCOUNT, BITRESET, BITREVERSE, BITSET,
BITXOR, LEN, SFT.

BITRESET(n,x)
the value given by resetting the n-th bit of x.
Inp:	integers (>= 0).
Out:	integer.
Ex:	BITRESET(0, 5) = 4, BITRESET(1, 5) = 5.
See:	BIT, BITAND, BITCOUNT, BITOR, BITREVERSE, BITSET,
BITXOR, LEN, SFT.

BITREVERSE(n,x)
the value given by reversing the n-th bit of x.
Inp:	integers (>= 0).
Out:	integer.
Ex:	BITREVERSE(0, 5) = 4, BITREVERSE(1, 5) = 7.
See:	BIT, BITAND, BITCOUNT, BITOR, BITRESET, BITSET,
BITXOR, LEN, SFT.

BITSET(n,x)
the value given by setting the n-th bit of x.
Inp:	integers (>= 0).
Out:	integer.
Ex:	BITSET(0, 5) = 5, BITSET(1, 5) = 7.
See:	BIT, BITAND, BITCOUNT, BITOR, BITRESET, BITREVERSE,
BITXOR,	LEN, SFT.

BITXOR(x,y)
bitwise logical-XOR of x and y.
Inp:	integers (>= 0).
Out:	integer.
Ex:	BITXOR(3, 5) = (0011B xor 0101B = 0110B) = 6.
See:	BIT, BITAND, BITCOUNT, BITOR, BITRESET, BITREVERSE,
BITSET,	LEN, SFT.

See:	the "User Programs" section.
Arguments must be simple variables.

BLOCK array(index,index...)
Assigns values to the specified array members.
Ex:	block A(2..4, 3..6) = X
assigns X to each A(i, j) for i=2,3,4 and j= 3,4,5,6.

block A(*,*) = X
assigns X to all the elements.

block B(0..2) = block A(2, 1..3)
assigns A(2, 1) to B(0), etc.

swap block B(0..2), block A(2, 1..3)
swaps the values.

Note that a double exchange occurs when overlapping
parts of one array are specified. In this case, results
are unpredictable.

clr block A(2..3,4..5)
sets to zero (same as block A(2..3,4..5)=0).

neg block B%(0..5)
changes signs.

You can also use expressions such as

block A(2..4) += expression
block A(2..4) += block B(3..5)

and these with + replaced by -, *, /, \, and @.
The first of these is the same as
A(2)=A(2)+(expression):A(3)=A(3)+(expression)
:A(4)=A(4)+(expression)
Note the parenthesis in the right hand side.
In the second, you cannot add any term to the right
hand side.

Note:	When a user-defined function is called in the middle of
the calculation of an index or an expression, BLOCK
used in this function creates an error.
When BLOCK is used on both sides of an expression, the
number of the indices must be the same though the
composition may vary.

See:	CLR, NEG, SWAP.

CALL short_array_name([arg1,arg2,...])
Calls a user machine language program after the
arguments are set.
See:	the "User Programs" section.

(Ed Thelen's comment - a subroutine call in USASIC is gosub *xxx(param1, param2,...) )

CANCEL for<,for,for,...>
Cancels the current for-next loop before jumping out
of it.
Ex:	cancel for:goto 100
cancel for,for:I=I+1:goto 200
Note:	Use GOTO to specify where to jump.
GOTO is necessary, unlike 'break' or 'cancel'
statements in other languages.
See:	FOR.

CEIL(x)
The smallest integer not less than x.
Inp:	integer, real, rational.
Out:	integer.
Ex:	CEIL(12345/100) = 124, CEIL(-12345/100) = -123.
See:	FIX, FLOOR, INT, ROUND.

CHR(ASCII code)
Inp:	integer. Signs are neglected.
Out:	character/string.
Ex:	print chr(65)    result:A
See:	ASC.
Note:	The format of hexadecimal expression is not '&h..' but
'0x..'.

CIRCLE (x,y),r,c
Draws a circle with center (x,y) and radius r.
CIRCLE (x,y),r,c,"f",paintcolor
Also fill inside with paintcolor.
CIRCLE (x,y),r,c,start_angle,end_angle
Draws an arc from start_angle to end_angle.
CIRCLE (x,y),r,c,start_angle,end_angle,"f",paintcolor
Draws a sector from start_angle to end_angle and
fill inside with paintcolor.

To draw an ellipse, replace r to (rx,ry).  For example:
CIRCLE (x,y),(rx,ry),c
Draws an ellipse with center (x,y), x-radius rx

Note:	Paintcolor can be replaced by tilepattern.
Tilepattern must be a string longer than 3 bytes.

CLOSE
CLOSE [#n]
CLOSE file1[,file2,...]
Closes the open files.  If no file name (or file
number) is given, then it closes all the open files.
See:	EOF, OPEN.

CLR variable1[,variable2,...]
Sets the variables to zero.  "CLR A" is faster than
"A = 0".
Ex:	clr A,B,C
sets A, B, C to 0.
See:	DEC, INC, NEG.

CLR BLOCK arrayname(index)
Sets the specified members of an array to 0.
Ex:	clr block A(0..10)
sets from A(0) to A(10) to 0.
clr block A(2,1..3)
sets A(2,1),A(2,2),A(2,3) to 0.
See:	BLOCK for details.

CLR TIME
Sets the clock to "00:00:00".  Effective only inside
UBASIC86.
It does not initialize the system clock, so there may
be an error of up to one second.

CLS [n]
Clears the screen.
Inp:	none or integer 1, 2, 3.
Note:	Clears the text screen and/or the graphic screen.
Ex:	10	console 0,25:cls

CCOEFF(polynomial)
Constant term of polynomial.
Ex:	A=poly(1,3,5):print ccoeff(A)    result: 1
See:	COEFF, LCOEFF.

COEFF(polynomial,degree)
Coefficient of the term of specified degree of
polynomial.
COEFF(polynomial, degree)=expression
Assigns a value to the coefficient of the term of
specified degree of polynomial.
Inp:	argument1 is a polynomial or 0.
argument2 is an integer (>= 0).
Ex:	A=poly(1,3,5):print coeff(A,2)    result: 5
A=0:coeff(A,3)=2:coeff(A,0)=5:print A
result: 2*X^3 + 5.
See:	CCOEFF, LCOEFF, POLY.

COLOR(n)
Specifies text color. (0 <= n <= 7)

COLOR=(palettecode, colorcode)
Assigns colorcode to palettecode.
Inp:	0 <= palettecode <= 15.
0 <= colorcode <=0xffffff
Ex.	color=(1,0xff0000)  result:palette 1 becomes pure RED.

COMBI(n,r)
Number of combinations extracting r elements from n
elements.
Inp:	integer n (0 <= n < 65536).
Out:	integer.
Ex:	print combi(4,2)    result: 6

CONJ(x)
Complex conjugate of x.
Inp:	number.
Out:	number.
Ex:	print conj(1+2#i)    result: 1-2#i
See:	IM, RE.

CONSOLE start line,lines in console area[, function key display
switch(0/1)]
Declares the console window area.
Note:	When the second argument is '*',the number of lines is
set to the maximum.
Settings are initialized when no argument is given.
Inp:	Start_line is from 0 to 24.
Lines_in_console_area is from 5 to 25.
Function_key_display_switch is 1 (displays) or 0 (not
displays).
Ex:	console 0,20,0
sets the console area to 20 lines starting from
line 0 (to line 19), and displays no function keys.
console 0,*
sets the console area full and clears the function
key desplay.

CONT
See:	STOP.

COPY x
Print out a display screen.
Note:
Shift+PrintScreen also do this.
Supports only ESC/P printers.

COS(x)
Cosine of x.
Inp:	number.
Out:	number.
Ex:	print cos(1.23)    result: 0.3342...
See:	SIN, TAN, ACOS.
Appendix B for the algorithm.

COSH(x)
Hyperbolic cosine of x.
Note:	(exp(x)+exp(-x))/2
Inp:	number.
Out:	number.
Ex:	print cosh(1.23)    result: 1.8567...
See:	SINH.
appendix B for the algorithm.

CREATE
Ex:	open "file_name" for CREATE as #n
See:	OPEN.

CUTLSPC(string)
Cuts off the spaces in the left end of a string.
Inp:	string.
Out:	string.
Ex:	print "A";cutlspc("	B C")    result:AB C

CUTSPC(string)
Cuts off all the spaces in a string.
Inp:	string.
Out:	string.
Ex:	print "A";cutspc("	B C")    result:ABC

CVR(x)
Decimal expression of the numerator of rational
divided by the denominator.
Inp:	integer, decimal, rational.
Out:	real.  argument itself if it is not rational.
Ex:	print cvr(1//3)    result: 0.3333...

DATA expression1[,expression2,...]
Note:	A string must be put in " ".
Commands placed after DATA in the same line are
neglected.

DATE
String containing current date and time.
Ex:	print date
displays current year, month, day, hour, minute and
second.
Out:	string.
Note:	CLR TIME does not affect the time represented by DATE.

DEC variable1[,variable2,...]
Decrements the variables.  "DEC A" is faster than
"A = A - 1."
The variable must currently hold integer values.
Ex:	A=100:dec A:print A    result: 99
See:	CLR, INC, NEG.

DECODE(ENCODEd_string)
Original string of an ENCODEd string.  Tokens are
separated by a space.
Ex:	print decode(encode("x+sin(abc)"))
result: X + sin( Abc )
See:	ENCODE.

DEF FNfunction name =
Ex:	10   A=2:B=3:C=4
20   def fnA(X,Y,Z)=X+Y-Z
30   print fnA(A,B,C)
Note:	def fn can be set anywhere in the program. For example
in the above, lines 20 and 30 can be exchanged.

DEFSEG = segment
Specifies the segment to be accessed by PEEK and POKE.
Note:	 Do not put a space between DEF and SEG.
See:	PEEK, PEEKW, PEEKS, POKE, POKEW, POKES, VARPTR.

DEG(polynomial)
Degree of polynomial.
Note:	Degree of 0 is defined to be -1, different from usual
definition.
Ex:	A=poly(0,0,1):print deg(A)    result: 2
See:	LEN.

DELETE [linenumber1] - linenumber2
Deletes the portion of the program.

DEN(rational)
Denominator of the argument.
Inp:	integer, rational.
Ex:	print den(2//3)    result: 3
See:	NUM.

DIFF(polynomial)
Differential of polynomial.
Ex:	A=poly(1,1,1):print diff(A)    result: 2*X + 1

DIM arrayname(bound1[,bound2[,bound3]])
Declares arrays, specifies the number of indices and
sets all the members of the arrays to 0.
Note:	The indices start at 0.
The bounds are nonnegative integers such that
bound1 <= 65534,  (bound2 + 1) * (bound3 + 1) <= 65535.

In subroutines and functions, declarations of arrays
must be placed at the beginning, not in the middle.
The arrays declared in a subroutine or function are
valid only in that subroutine or function and are
erased by RETURN.

EMA-arrays are NOT automatically erased by RUN.  So it
is recommended to place EMAWORD just before DIM EMA().
See:	ERASE.

DIR ["pathname"]
Displays the names of the programs on a disk.
The path can contain wildcard match characters.
Ex:	dir "a:\bin\a*.*"
displays the file names beginning with 'a' in the
\bin directory of drive A.

Note the following symbols:
+	data file
*	machine-language program
p	write protected
Sizes are given in 100 bytes.
See:	LDIR

DIR="path"
Changes the current directory.
Ex:	dir="b:"
Changes the object of LOAD and SAVE to drive B.
Note:	Do not put '\' at the end of path name.

DIR
gives the current drive name and directory name.
Inp:    nothing.
Out	string.
Ex:	DirMemo=dir:dir="b:":do something:dir=DirMemo
some other directory.

DOSCMD
Executes command.com.

DOSCMD string
Invokes the command.com file to execute a DOS command.
Ex:	DOSCMD "dir b:"
temporarily transfers control to MS-DOS to execute
'dir b:'.  But the display is cleared at once and
control is returned to UBASIC86.
DOSCMD "program name" runs the specified program.
Note:	A program using graphic areas may destroy the work area
of UBASIC86.
You may destroy the screen #1 of graphic RAM.

DOT(x,y)
Palette code of a point (x,y)

EDIT [line_number or label]
Displays a screenful of the current program including
the specified line.
The default line is the previously specified or edited
line, or the line on which the most recent error
occurred.

ELSE
See:	IF.

ELSEIF
See:	IF.
Note:	Do not put a space between ELSE and IF.

EMA([expanded_array_number];index1,index2)
Specified member of an EMA-array.
Ex:	print ema(1;2,3)
displays the member(2,3) of EMA #1.
See:	EMA-array.

EMAWORD expression
Specifies the size of a member of an EMA-array.
Note:	Do not put a space between EMA and WORD.
See:	EMA-array.

ENCODE(string)
Converts a string containing an expression or command
to internal codes.
Note:	This makes VAL faster.
See:	VAL, DECODE.

END
Closes all files and ends program execution,
sends a newline character to the printer if necessary,
and cancels unterminated loops.

ENDIF
See:	IF.
Note:	Do not put a space between END and IF.

ENDLOOP
See:	LOOP.
Note:	Do not put a space between END and LOOP.

EOF(n)
1 if the content of file #n is exhausted, 0 otherwise.
Inp:	integer.
Out:	integer (0 or 1).
Ex:	10	open "abc" for input as #1
20	while not eof(1)
30	  input #1,a
40	  print a
50	wend
60	close
Continues to read until the data are exhausted.
If EOF is not checked, an error occurs when the data
are exhausted.

ERASE array1 [,array2,... ]
Erases arrays.  Array names must be followed by
parentheses, e.g. "erase a()".  If the arrays a(m) and
b(n) are DIMensioned in this order, then it is faster
to erase b(), then a().  ERASE should not be used in
subroutines and functions.  Arrays created in
subroutines and functions are erased automatically by
RETURN.
See:	DIM.

ERROR GOTO [line_number or label]
Note:	Usually, a program stops if an error occurs.  However,
if a routine to handle errors has been specified by
ON ERROR GOTO, the execution proceeds to that routine.
Ex:	10	on error goto *ErrorTrap
20	print 1/0
30	end
40	*ErrorTrap
50	print "error"
60	end
A "division by zero" error occurs in line 20.  Then
the execution continues from line 40 as specified in
line 10.
Note:	This statement does not work well. There is no "resume
statement".  And this clears all the work areas
concerning control of execution, so a program will not
be executed normally if the error handling routine is
designed to jump back to the subroutine where error has
occurred.  This statement is recommended only in
programs which have a main menu and branches out of it.
See:	GOTO.

EUL(n)
Euler's function of n.
Inp:	integer n (1 <= n <= 4294967295).
Out:	integer.
Ex:	print eul(100)    result: 40

EVAL(string)
Interprets a string as a command and executes it.
Note:	It is recommended to ENCODE the string if you want to
evaluate it often.
Ex:	eval("list "+str(x))
lists the lines specified by x.
See:	VAL.

EVEN(n)
1 if n is even, 0 if odd.
Ex:	print even(10),even(11)    result: 1	0
See:	ODD.

EXIST("filename")
1 if the file specified by "filename" exists, 0
otherwise.
Out:	integer (0 or 1).
Note:	An error occurs if you try to OPEN a file which does
not exist.  The purpose of  the EXIST function is to
avoid that error.
Note:	Extension of filename cannot be omitted.
Ex:	if exist("abc.ubd") then open "abc.ubd" for input as #1

EXP(x)
e to the x.
Ex:	print exp(1.23)    result: 3.4212...
See:	Appendix B for the algorithm.

FACTORIAL(n)
Factorial of n.
Inp:	integer n (0 <= n <= 1014).
Out:	integer.
Ex:	print factorial(12)    result: 479001600
Note:	!(n) is equivalent.

FILE
See:	OPEN.

FILE1(n1,n2), FILE2(n1,n2), FILE3(n1,n2)
Random files declared by OPEN statements.
Ex:	open "x" as file1(100):file1(12)=100:print file1(12):close file1

Special elements:
FILEi(-1) = total number of elements - 1
FILEi(-2) = element word size
FILEi(-3) = POINT WORD length
FILEi(-4) = max of 1st indices (= FILEi(-1) if 1 dimensional)
FILEi(-5) = max of 2nd indices
See:	Random files.

FILE2
See:	FILE1.

FILE3
See:	FILE1.

FILES
See:    DIR.
For compatibility purposes with other Basics this command is
also included

FIND(x,a(i),n)
(Index - i) of the first occurrence of x in  a(i), ...,
a(i+n-1).
A negative value is returned if none is equal to x.
The array must be sorted in ascending or descending
order.
Binary search is used.
Inp:	x and a(i) are integer or real. n is an integer.
Out:	integer.
Ex:	find(3,A(2),10)
if the return value is 4, a(6) is 3 (not a(4)).

FIX(x)
Integer part of x, truncating towards zero.
Inp:	integer, real, rational.
Out:	integer.
Note:	The result may differ from that of INT(x) when x is
negative.
Ex:	print fix(12345/100)     result: 123
print fix(-12345/100)    result:-123
See:	CEIL, FLOOR, INT, ROUND.

FLOOR(x)
The greatest integer not exceeding x.(same as INT)
Inp:	integer, real, rational.
Out:	integer.
Ex:	FLOOR(12345/100) = 123, FLOOR(-12345/100) = -124.
See:	CEIL, FIX, INT, ROUND.

FN function name (arg1, arg2, ...)
Begins a user-defined function name.
Ex:	100	a=fnMAX(A,B)		     'Calls function
...
200	fnMAX(X,Y)		    'Declaration of
a function
210	  local 		    'Definition of
a local variable
220	  if X>=Y then Z=X else Z=Y
230	return(Z)		    'Returns a value
Note:	You may type '.' for 'fn'.
See:	"Subroutines and Functions" for details.

FOR variable = initial_value TO final_value [STEP increment]
NEXT [variable]
All the values must be integers.  The number of
iterations is determined at the beginning of the loop
as
(final_value - initial_value) \ increment + 1
(see the NOTE below)

which may not exceed 4294967295.  If it is zero or
negative, the loop is not executed, however the
assignment of the initial_value to the loop variable is
executed.
The loop cannot be terminated by changing the value of
the loop variable in it.  When the loop is terminated
normally, the value of the loop variable is
initial_value+number_of_iterations*increment.
To jump out of the for-next loop, use CANCEL FOR.
Ex:	10	S=0
20	for I=1 to 100
30	  S=S+I:if S>100 then cancel for:goto 50
40	next I
50	print I;S
60	end

NOTE:   The evaluation of the final_value is done after the
assignment of the initial_value to the loop variable.
Thus if the final_value is a formula containing the
loop variable, the number of iterations will be
different from that seems to be.
Ex: X=1:for X=X-1 to X:print X:next X
is executed only for X=0.
Do not use this kind of parameters.

FREE
Displays the size of the available program area and
stack area.
Note:	The available text area (=program area) shows how many
more bytes of program codes you may write.
The available stack area shows how many words in the
256 words of system stack have never been used (not
"are not being used now").  This is to monitor the
system and can usually be ignored.

FREEZE ["filename"]
Writes the current program, variables, and other
information on to a disk.  If you HALT and FREEZE the
program execution, you can MELT and CONTinue it later.
The size of the frozen file is 100k-300k bytes.
Note:	You can MELT the frozen information.  The filename
should not contain an extension since ".ice" is
automatically added.  "UB.ICE" in the current drive is
used if the filename is not given.
The disk must have 200k-500k bytes of free area.  The
latter half of UBASIC86 and variable areas are frozen.
FREEZE does not save the area of memory used by a
machine-language program that is not in a UBASIC86 array.
MELT does not work if the arrangement of memory has
been changed.  This occurs when CONFIG.SYS is modified
or memory resident programs are loaded.

In ordinary BASIC, when you want to do another job
while running a program which takes a lot of time, you
have no choice but to abort the running program or to
give up the new job.  There is no satisfactory solution
as DOS does not currently support multi-tasking.
However, to FREEZE the running program is an effective
solution.
Ex:	1) Stop the running program by ctrl+BREAK or ctrl+c.
2) FREEZE the current status of memory on to a disk.
3) Start and finish another job.
4) MELT the frozen memory.
5) Continue the program by CONT.

See:	MELT.

GCD(m,n)
Greatest common divisor of m and n.
Inp:	integer, rational polynomial or modulo polynomial.
Out:	integer(>=0), rational polynomial or monic modulo
polynomial.
Ex:	print gcd(14,21)    result: 7
print gcd(_x^2-1, _x^2-2*_x+1)    result: 2*x - 2
See:	LCM, REDUCE.

GCOLOR palettecode
Decides a color for GPRINT.

GET(x1,y1)-(x2,y2)
Bit patterns in the specified graphic plane.
Ex:	A#=get(100,200)-(120,240)
Note:	44*44 is a maximum size.
See:	PUT

GETENV("environment variable name")
contents of environment variables.
Inp:	string.
Out:	string, 0 if no such name exists.

See:	GSAVE.

GLOCATE (x,y)
Moves a pointer of GPRINT to (x,y).
See:	GPOSX, GPOSY

GOSUB line_number or label
Calls the subroutine.
GOSUB label(parameter1,parameter2,...)
Calls the subroutine with parameters.
Note:	The subroutine called must have the same format of
arguments.
If an argument is a variable or an expression, the
current value of it is assigned to the corresponding
variable.  The previous value of the variable is pushed
on to the stack and restored by the corresponding
RETURN.
Variables can be passed by address (use &).
The corresponding variables share the same memory area.
Array names must be followed by "()".

Ex:	10	A=1:B=2:C=0
20	gosub *MAX(A,B,&C)    :'A,B are passed by value
30	print C		      :'&C is passed by address
40	end		      :'thus in *MAX, Z is
identified with C
100	*MAX(X,Y,&Z)	      :'X and Y are local
variables in *MAX
110	  if X>=Y then Z=X else Z=Y
:'they do not change X
and Y in the main
120	return		      :'routine if variables
of the same name exist.
Note:	A simple short variable cannot be passed by address,
i.e.  gosub *ABC(&A%) is not allowed.
An array can be passed by address,
i.e.  gosub *ABC(&A()) is allowed,
but a member of an array cannot be passed by address,
i.e.  gosub *ABC(&A(1)) is not allowed.
An array can be passed by value also.
i.e. gosub *ABC(A()) passes all the members by value.

GOTO line_number or label
Goes to the specified line.

GPOSX
x-pointer of GPRINT

GPOSY
y-pointer of GPRINT

GPRINT
Prints numbers and strings on the graphic plane.

GSAVE ["filename"]
Saves a graphic to a file.

GSIZE width, height, width2, height2
Decides a size of a character for GPRINT.
Width2 and height2 include the blanks between next
characters.  GSIZE without any parameter initializes
the sizes.

HEX(n)
Note:	Converts the internal expression of n to a string. If
n is an integer or a decimal, the string begins with
highest byte. Otherwise, it begins with lowest byte.
Take care with rationals and complex numbers, since one
byte has 2 digits and there is no separator between
the bytes.
Ex:	print hex(65534)    result:fffe
print hex("abc")    result:616263
Note:	The format of a hexadecimal expression is not '&h..'
but '0x..'.

IF
1)IF expression THEN statements [ENDIF]
If the value of the expression is not zero, then the
statements after THEN are executed.

2)IF expression THEN statements ELSE statements [ENDIF]
If the value of the expression is not zero, then the
statements after THEN are executed; otherwise the
statements after ELSE are executed.

3)IF expression THEN statements ELSEIF expression THEN
statements  ELSEIF ...	... ELSE statements [ENDIF]
This form is used for multiple branching.
The expressions are evaluated in order and the
statements after THEN after the first nonzero
expression are executed.
When all the expressions are zero, the statements after
ELSE are executed.

Note:	ENDIF may be omitted if the next line is not
a continuation.  ELSE and ENDIF correspond to the
nearest IF before them.
A ":" between statements can be omitted before and
after IF, THEN, ELSEIF, ELSE, and ENDIF.

Continuation of a line:
The statements can be written in multiple lines.
A line beginning with a colon (:) is a continuation of
the previous line.

Thus, the program portion

10	if A<>1 then *ABC
20	B=1:BB=10
30	C=11:CC=110
40	*ABC

is equivalent to

10	if A=1 then
20	  :B=1:BB=10
30	  :C=11:CC=110

Note that statements after REM (or ' ) may be regarded
differently.  In the following line, "B=1" is not
executed as it is regarded as a comment:

10	A=1:'TEST:B=1

But in the following lines, "B=1" is executed:

10	A=1:'TEST
20	:B=1

The ENDIF in

10	if A then B else C: D endif

may be omitted, but not in

10	if A then B else C endif D

which is equivalent to

10	if A then B else C
20	D

"If then else" may be nested.  The line

10	if A then if D then E else F: C

is equivalent to

10	if A then
20	:if D then E else F
30	:C

whereas the line

10	if A then if D then E else F endif C

is equivalent to

10	if A then
20	:if D then E else F endif
30	:C

Multiple IF:

10	if A then B:C

If you want to replace B by the construction "if D then
E else F", do not simply insert it thus:

10	if A then if D then E else F:C

because C would then be regarded as a continuation of
the ELSE statement F and would be executed only when A
is nonzero and D is zero.  So in this example ENDIF,
which was omitted in the original line, must be
restored in this way:-

10	if A then if D then E else F endif C

The line continuation (:) makes the above complicated
line plain:

10	if A then
20	:if D then E else F endif
30	:C

The following lines have a different meaning, as
mentioned above:

10	if A then
20	:if D then E else F
30	:C

Multiple branching:
Multiple branching is realized by continuation of lines
and ELSEIF.

10	input A
20	if A<=10 then print 1
30	:elseif A<=20 then print 2
40	:elseif A<=30 then print 3
50	:elseif A<=40 then print 4
60	:else print 5

displays 1, 2, 3, 4 when A<=10, 10

IM(x)
Imaginary part of x.
Inp:	number.
Out:	number.
Ex:	print im(123+456#i)    result: 456
See:	CONJ, RE.

INC variable1 [,variable2,... ]
Increments the variables.  "INC A" is faster than
"A = A + 1".
The current value of the variable must be an integer.
Ex:	A=100:inc A:print A    result: 101
See:	CLR, DEC, NEG.

INKEY
Checks keyboard buffer.
Note:	Character in the keyboard buffer if there is any, null
string otherwise.
Out:	character.
Ex:	10	while inkey=""
20	  gosub 100
30	wend
repeats the subroutine beginning at line 100 until
any key is pressed.

INP(port#)
Inputs from the input port specified by port#.
Inp:	integer.
Out:	integer.
See:	OUT.

INPUT
1) INPUT ["prompt";] variable1 [, variable2, ... ]
Waits for a number or an expression and assigns its
value to the variable.  If more than one variable is
specified, separate the input numbers/expressions by
commas.
Note:	UBASIC86 looks for the first "?" on the cursor line
and takes everything after it as input.  UBASIC86
supplies a prompting "?", so do not include one in
your "prompt".  You can input anything on screen by
moving the cursor to it and preceding it by a "?".
Input is passed through the UBASIC86 interpreter, so
it can include formulae and variable names.
To clear the key buffer, use the function input\$(0),
which does not input a key.
Ex:	10	input "Enter a number:";A
20	print A
See:	INKEY, STRINPUT.

2) INPUT = "filename"
Redirects the input to the specified ASCII file.
Characters other than numerals and periods are
interpreted as delimiters.
INPUT = INPUT cancels the redirection.
See:	STRINPUT.

3) open "filename" for INPUT as #n
See:	OPEN.

INPUT\$(n)
Waits for n keystrokes, then returns them as a string.
Note:	If n > 0 , the cursor is displayed.
If n < 0 , the cursor is not displayed.
If n = 0 , only the key buffer is cleared (otherwise
it is not cleared).
Inp:	integer.
Out:	string.
Ex:	10	A=input\$(-1)
waits for a keystroke without displaying the cursor.
Note:	Note that "\$" is needed, unlike other string functions
in UBASIC86.

INPUT #n, var1 [,var2,...]
Reads the value(s) of the variable(s) from file #n
(n = 1, 2, ...).
Note:	Multiple values can be read with one INPUT # statement.
Variables must be marked off with ",".
See:	CLOSE, EOF, OPEN.

INSTR([n],string1,string2)
Scans string1 starting from n-th character of string1
for the occurrence of string2 and returns the location
of the first character of string2.
Returns 0 if string2 does not occur.
Inp:	n is an integer.
Out:	integer.
Ex:	print instr("abcbcacab","ca")    result: 5
See:	INSTR2.

INSTR2([n],string1,string2)
Scans string1 starting from n-th character of string1
for the first occurrence of any character contained IN
string2 and returns the location of the character.
Returns 0 if none of the characters occur.
Inp:	n is an integer.
Out:	integer.
Ex:	print instr2("abcbcacab","ca")    result: 1
See:	INSTR.

INT(x)
The greatest integer not exceeding x.(same as FLOOR)
Inp:	integer, real, rational.
Out:	integer.
Ex:	INT(12345/100) = 123,INT(-12345/100) = -124.
See:	CEIL, FIX, FLOOR, ROUND.

IRND
Integer valued random number from 0 to 32767.
Out:	integer i (0 <= i <= 32767).
Note:	Negative integers do not occur.
Ex:	10	randomize
20	for I=1 to 100
30	  print irnd;
40	next
displays 100 integer valued random numbers.
See:	RANDOMIZE, RND.
appendix B for the algorithm.

ISQRT(x)
Integer part of the square root of x.
Note:	Returns precisely the largest integer not exceeding the
theoretical value.
Inp:	integer.
Out:	integer.
Ex:	print isqrt(10)    result: 3
See:	SQRT.

JUMP
Goes to the next "**", as in
10	if a=1 then jump
20	b=1
30 **: c=1

Note:	It is easy to find where to jump unlike GOTO.

KEY key_number,string
Modifies the settings of function keys, etc.
Key number is as follows:
1  - 10 f1 - f10
Ex:	key 1,"run "+chr(0x22)+"pi"+chr(0x22)+chr(0x0d)

assigns 'run "pi"' to function key #1.

KILL "filename"
Kills a program or a data file.
Note:	If the filename is without extension, the file is
regarded as a program with ".UB".
If "+" is added in place of extension, the file is
regarded as a data file with ".UBD".
To specify a file without extension, add "." to the
filename.
See:	SET.

KRO(m,n)
Extended Kronecker's symbol for m and n.  Equivalent to
Legendre's symbol (for quadratic residue) for odd
prime n.
That is, 1 if m is a quadratic residue modulo n, -1 if
m is a non-quadratic residue, 0 if m can be divided by
n.
Also equivalent to Jacobi's symbol for odd composite n.

Inp:	integer.
Out:	integer (0, 1, or -1).
Ex:	print kro(3,5)    result:-1.

LCM(m,n)
Least common multiple of m and n.
Inp:	integer, rational polynomial or modulo polynomial.
Out:	integer(>=0), rational polynomial or monic modulo
polynomial.
Ex:	print lcm(14,21)    result: 42
print lcm(_x^2-1, _x^2-2*_x+1)
result: (1//2)*X^3 - (1//2)*X^2 - (1//2)*X + 1//2
See:	GCD.

LCOEFF(polynomial)
Coefficient of the term of highest degree of polynomial.
Ex:	A=poly(1,3,5):print lcoeff(A)    result: 5
See:	CCOEFF, COEFF, POLY.

LDIR "pathname"
Outputs a list of files to the printer.
Usually the pathname is simply the drive name (a:, b:,
etc.).
A wild card is allowed.
See:	the MS-DOS manual for detailed information.
DIR.

LEFT(string[,n])
n characters at the left end of a string.
It returns one character when n is not given.
Ex:	print left("abcdefgh",3)    result:abc
See:	MID, RIGHT.

LEFT(packet[,n])
The packet which contains the n members at the left end
of the specified packet.
Note:	It returns a packet with one member when n is not given.
Use MEMBER to get a member itself.
Ex:	print left(pack(1,2,3,4,5),3)    result:( 1, 2, 3)
See:	MEMBER, MID, RIGHT, PACK.

LEN(x)
Bit length of x.  LEN(0) = 0, LEN(1) = 1, LEN(5) = 3,
Note:	It returns byte length when argument is a string,
number of data when argument is a packet, and number of
terms (degree+1) when argument is a polynomial.
Inp:	any data.
Out:	integer.
Ex:	len(0)=0, len(1)=1, len(5)=3, len(65535)=16,
len(65536)=17, len("abc")=3
A=pack(1,2,3):print len(A)    result: 3
A=poly(1,2,3):print len(A)    result: 3 (note deg(A)=2).

LINE (x1,y1)-(x2,y2),c
Draws a line from (x1,y1)-(x2,y2) with color c.
LINE (x1,y1)-(x2,y2),c,"b"
Draws a box from (x1,y1)-(x2,y2) with color c.
LINE (x1,y1)-(x2,y2),c,"bf",paintcolor
Also fill inside with a paintcolor.
LINE (x1,y1)-(x2,y2),c,"bf",paintcolor
Also fill inside with a paintcolor.

LIST [linenumber1 or label1] [ - linenumber2 or label2]
Displays the specified portion of the current program.
To halt, press Control-S.  To quit, press Control-C.
Note:	To edit a program, EDIT,  and  are
recommended.
See:	EDIT.

LLIST [linenumber1 or label1] [ - linenumber2 or label2]
Same as LIST, but outputs to both the printer and the
screen.
Note:	To halt, press Control-S.  To quit, press Control-C.
Note that a printer with a buffer does not stop at
once.

LLOCATE n
Sends a carriage return (but not line feed) and n
blanks to the printer.
See:	LOCATE.

standard (ASCII) text files is slower because they need
to be converted to the internal code.
If you do not give the program_name, the list of
programs is displayed so that you may select a program
using the arrow keys and <Enter>.  (hit  to quit)
See:	APPEND, SAVE.

(Note added by Ed Thelen - ASCII text files MUST be line numbered.)

LOCAL variable1[=value],variable2[=value], ...
Defines local variables and initializes them (default
= 0).
Note:	Local variables must be defined just after the
subroutine/function definition.
Variables defined by LOCAL are valid until the
subroutine/function RETURNs.  They are distinguished
from variables of the same name in the main program.
Local variables are initialized to zero if the value is
not specified.
Do not LOCAL the arguments of the subroutine/function,
since arguments are automatically defined as local
variables.
100	fnABC(X,Y,Z)
110	local I,J,K,Z
sets to 0  the value of Z passed by the main program.
Ex:	 10	for I=1 to 10
20	  gosub *ABC(I)
30 	next
40 	end
100 	*ABC(X)
110	  local I	:' This 'I' is not the 'I' in
the main routine.
120	  for I=1 to X
130	    print X;
140	  next
150	  print
160	return

The variable I is used in both the main routine and the
subroutine.
The value assigned by LOCAL in line 110 does not affect
the value of I in the main routine.
initialized by LOCAL.

LOCATE x, y
LOCATE x
LOCATE , y
Specifies the cursor position on the screen.
Note:	Locate X changes the x-coordinate.  The y-coordinate
remains as it was.
Locate ,Y changes the y-coordinate.  The x-coordinate
remains as it was.
See:	LLOCATE, POSX, POSY.

LOG(x)
Natural logarithm of x.
Inp:	number.
Out:	real, complex number.
Ex:	print log(1.23)    result: 0.2070...
See:	appendix B for the algorithm.

LOOP - ENDLOOP
Constructs an infinite loop.
Note:	You may jump out of the loop using GOTO.
Ex:	10	loop
20	...
30	...
40	endloop

is equivalent to:

10	'
20	...
30	...
40	goto 10

However, the loop structure is emphasized in the former
case.
See:	ENDLOOP.

LOWER(string)
Translates characters to lowercase.
Inp:	string.
Out:	string.
Ex:	print lower("BecauseIt'sTime.")
result:becauseit'stime.
See:	UPPER.

LPRINT
1) LPRINT expression
LPRINT USING(x, y), expression
LPRINT "string"
LPRINT CHR(n)
Outputs to the printer.
Note:	Multiple expressions can be output with one LPRINT
statement.
Expressions must be marked off with ";" or ",".
"LPRINT A;B" prints the values without spaces in
between.
"LPRINT A,B" prints the value of B on the next
8-character field.
See:	LLOCATE, ALEN, USING.
Note for DOS users:
LPRINT may not function when the use of print.sys is
not declared in config.sys in DOS version 3.1 and
later versions.
Place the "print.sys" in the system diskette of DOS
and add the "config.sys" the following line (See DOS
manual for details.):
device = print.sys
See:	DOS manual for details.

2) LPRINT = PRINT + LPRINT + "filename"
Redirects the outputs of LPRINT statements to the
screen (PRINT), the printer (LPRINT), a file
("filename"), or any combination of these.  No
more than one file is allowed on the right-hand side.
The file must be distinct from the one specified by
the "PRINT = ..." construct.
The outputs are redirected to NULL if nothing is on
the right-hand side.

LVLIST [line_number1 or label1][-line_number2 or label2]
Outputs to the printer the list of variables used in
the program.
See:	VLIST.

LVXREF [variable]
Outputs to the printer the cross-reference list for all
(or the specified) variables.  Array names must be
followed by a (.
See:	VXREF.

LXREF [line_number or label_1] [-line_number or label_2]
Displays/prints the line numbers of the lines that
reference the specified lines. Press Control-S to halt,
Control-C to quit.
Note:	If line_number or label is not specified, all the line
numbers and labels are regarded as the arguments.
See:	XREF.

MAPX(x)
Converts world x-coordinates to screen x-coordinates.

MAPY(y)
Converts world y-coordinates to screen y-coordinates.

MAX(arg1,arg2,...)
Returns the largest of the arguments.
Ex:	print max(1,3,2)    result: 3
print max("d","abc","ef")    result:ef
In string comparisons, the ASCII codes of the
characters are compared in order.
See:	MIN.

MELT ["filename"]
Melts a FREEZEd program.
Note:	Filename should not have an extension as ".ICE" is
If no filename is given, "UB.ICE" in the current
directory is used.
The MELTed program cannot be CONTinued after a fatal
error has occurred.  In that case, MELT it once again.
Results are unpredictable if a file is modified after
FREEZing the program in which it is OPENed.
See:	FREEZE.

MEMBER

1) MEMBER(string,n)
n-th member of the specified string. n starts from 1.
The members of the string are marked off by "," or a
space.  However, ","s or spaces between () are
neglected.
Ex:	A="123,abcdefg,mid(B,1,2)"
print member(A,1)    result:123
print member(A,2)    result:abcdefg
print member(A,3)    result:mid(B,1,2)
Note:	Use CUTSPC to delete the spaces if you do not want
them to be regarded as delimiters.
The return value is a string.  Use VAL to convert
it to a number.

2) MEMBER(packet,n)
n-th member of the specified packet. n starts from 1.
Ex:	print member(pack(11,22,33,44),3)    result: 33
See:	PACK.

3) MEMBER(packet,n)=expression
Replaces the n-th member of the specified packet.
n starts from 1.
Note:	If n is more than the current number of members,
0 is assigned to the n-th member and all the
members between the n-th and current members.
Ex:	A=pack(11,22,33,44):member(A,3)=55:print member(A,3)
result: 55
See:	PACK.

MID
1) MID(string,x,n)
Substring which starts with the x-th character of the
specified string and contains n characters.
x starts from 1.
Note:	To specify all the characters starting with the
x-th, use "*" as n or specify a larger n than the
length of the string.
It returns one character if n is not given.
Ex:	A="abcdefg"
print mid(A,2,3)	result:bcd
print mid(A,2,100)	result:bcdefg
print mid(A,2,*)		result:bcdefg
print mid(A,2)		result:b
See:	LEFT, RIGHT.

2) MID(packet,x,n)
The portion of the specified packet which starts with
the x-th member and contains n members.
x starts from 1.
Note:	Returns a packet with one member when n is not
given.
Use MEMBER to get a member itself.
Ex:	print mid(pack(11,22,33,44),2,2)    result: ( 22, 33)
See:	MEMBER, LEFT, RIGHT, PACK.

3) MID(String_variable, x, n)=string
Replaces n characters starting with the x-th character
of the specified string_variable by specified string.
x starts from 1.
Note:	If the string is shorter than n characters, the
rest of the characters are not replaced.
If the string is longer, the rest of the string is
neglected.
Ex:	A="abcdefg":mid(A,3,2)="xy":print A
result:abxyefg
Note:	There is no MID statement which replaces the
members of a packet.  Replace them one by one using
MEMBER.

MIN(arg1,arg2,...)
Returns the smallest of the arguments.
Ex:	print min(1,3,2)    result: 1
print min("d","abc","ef")    result:abc
In string comparisons, the ASCII codes of the
characters are compared in order.
See:	MAX.

MOB(n)
See:	MOEB.

MODINV(a,n)
Gives x such that a * x mod n = 1,  0 < x < n.
It returns 0 if no such x exists, i.e. if a and n are
not coprime.
Inp:	integer (n > 0).
Out:	integer.
Ex:	print modinv(23,45)    result: 2

MODPOW(a,b,n)
(a to the b) mod n.  Mod is taken each time a is raised in
order not to overflow.  b >= 0, n > 0.
Note:	If b = 0, it returns 1 neglecting the value of a.
Inp:	b must be integer b >= 0
a and n must be the same type: integer, polynomial or
modpolynomial. if a is integer then n must be positive.
Out:	same as a
Ex:	print modpow(12,34,56)    result: 16

MODSQRT(a,p)
Gives x such that x^2 mod p = a, 0 <= x < p.
Inp:	integers. a must be a square modulo p,
p must be a prime number.
Out:	integer.
See:	SQRT

MODULUS = expression
Sets the modulus (which must be prime, =< 65535) used
in the calculation of polynomials.
Set modulus = 0 (default value) when calculating normal
polynomials (with integral, rational or complex
coefficients).
Note:	UBASIC86 allows polynomials whose coefficients are
integers taken modulo a prime number.
Ex:	modulus=2:A=5*_X^2+6*_X+7:print A    result: X^2 + 1
Note:	Do not change the modulus during calculation with
polynomials.

MODULUS
Current value of modulus.

MOEB(n)
Moebius' function.
0 if n has a square factor.
If n has no square factor, 1 if n has an even number of
prime factors, -1 if n has an odd number of prime
factors.
Inp:	integer n (1 <= n <= 65536^2-1 = 4294967295).
Out:	integer.
Ex:	print mob(105)    result: -1

MONIC(polynomial)
Monic polynomial obtained by dividing the argument by
the coefficient of the highest degree.
Ex:	A=2*_x+1:print monic(A)
result:	X + 1//2	if modulus = 0
X + 2		if modulus = 3
X + 3		if modulus = 5.

NEG variable1 [,variable2,... ]
"NEG A" is equivalent to "A = -A", but faster.
Ex:	neg A,B,C
changes signs of A, B, C.
See:	CLR, DEC, INC.

NEG BLOCK array(index,index...)
Changes the signs of the specified array members.
Ex:	neg block A(0..10)
changes signs of the members from A(0) to A(10)
neg block A(2,1..2)
changes signs of A(2,1) and A(2,2)
See:	BLOCK for details.

NEW
Deletes the current program and variables.
Note:	A program NEWed by mistake can be REVIVEd.
See:	REVIVE.

NOP
No operation.  When the TRON command does not function
properly (e.g. in the case of multi-statements), put an
NOP just before the statement to be traced.
See:	TRON, TROFF.

NOT
IF NOT
WHILE NOT
UNTIL NOT
Changes logical values.
Note:	This is to emphasize "If .... is not true".
Ex:	while not eof(1)
input #1,A:print A
wend

is easier to understand than:

while eof(1)=0
input #1,A:print A
wend

NUM(argument)
Numerator of the argument.
Inp:	integer, rational.
Ex:	print num(2//3)    result: 2
See:	DEN.

NXTPRM(x)
The smallest prime greater than x.  It returns 0 if
either 	x < 0 or the result is greater than 2 to the
32nd.  x may be a noninteger.
Inp:	integer, real.
Out:	integer.
Ex:	print nxtprm(123.45)    result: 127

NEXT
See:	FOR.

ODD(x)
1 if x is odd, 0 if even.  x must be an integer.
Inp:	integer.
Out:	integer (0 or 1).
Ex:	print odd(10),odd(11)    result: 0	1
See:	EVEN.

ON
See:	ERROR.

OPEN
1) OPEN "filename" FOR INPUT (or OUTPUT or APPEND or CREATE) AS #n
Opens a sequential data file to be written and read by
"PRINT #n, ..." and "INPUT #n, ..." commands,
where n = 1, 2, 3, 4.
The filename may be with .UBD or without extension.
If the POINT value is changed after the file was written,
truncating or padding with zeros can occur.
If the file specified in "OPEN...FOR APPEND" is not
found, a new file is created.
Note:	CREATE options deletes the specified file if it exists
whereas WRITE option does not.
10 files (#1 ... #10) can be OPENed at the same time.
When you cannot open 10 files, increase the number of
open files declared in "config.sys".
"files = 20" is recommended.
Filename does not contain an extension.  Do not add "+"
to the filename even if it is a data file.
See:	CLOSE, EOF, EXIST, INPUT #, PRINT #.

2) OPEN "filename" FOR INPUT (or OUTPUT or APPEND or CREATE) AS #n
Opens a file in text-file form(=ASCII form).
The filename must have extension other than .UBD
Note:	CREATE options deletes the specified file if it exists
whereas WRITE option does not.
10 files can be OPENed at the same time.
Add "." to specify a filename without extension.
See:	CLOSE, EOF, EXIST, INPUT #, PRINT #.

3) OPEN "filename" [FOR CREATE] AS FILEn(m1[,m2]) [WORD w]
Uses files as a random file, where n = 1, 2, 3.
The upper bound for the array size = (m1+1)*(m2+1)
must be less than 2^31-1.
The word size of each array element is w (or current WORD
if not specified).
Protected files can be read, but not written.
Ex:	open "filename" for create as file1(n) [word x]
makes a new file.
open "filename" as file1
opens an existing file.
See:	CLOSE.
"RandomFIles" for details.

OR
expression1 OR expression2
0 if both arguments are zero, 1 otherwise.
Inp:	expressions.
Out:	integer (0 or 1).
Ex:	if A or B then
Note:	Both expressions are evaluated.

OR{expression1,expression2,...}
0 if all the arguments are zero, 1 otherwise.
Inp:	expressions.
Out:	integer (0 or 1).
Ex:	if or{A,B,...} then

When the expressions between {} are long,
continuation of lines (:) is allowed as follows:

if or{A,
:B,
:...}
:then
Note:	If one of the argument is nonzero, it returns 1 at once
without evaluating the following expressions.

OUT port#,expression
Outputs a value to the specified port.

OUTPUT
Ex:	open "file_name" for OUTPUT as #n
See:	OPEN.

PACK(arg1,arg2,...)
Makes data a packet.
Note:	It assigns multiple data to a variable.
Use MEMBER to get a member of a packet.
Ex:	A=pack(1,2,3):print A    result: ( 1, 2, 3)
See:	MEMBER, LEFT, MID, RIGHT.

PAINT (x,y)[,paintcolor,boundarycolor]
Paints by paintcolor a region with boundary having boundary
color.

PAUSE [period]
Pauses period times 100 milliseconds.
If period is not specified pauses 1 second.
Note:	The timing is not accurate.

The byte at the specified address.
Note:	Segment must be specified by DEFSEG.
See:	DEFSEG, PEEKW, PEEKS, POKE, VARPTR.

The word at the specified address.
Note:	Segment must be specified by DEFSEG.
See:	DEFSEG, PEEK, PEEKS, POKEW, VARPTR.

n bytes at the specified address.
Note:	Segment must be specified by DEFSEG.
Out:	string.
See:	DEFSEG, PEEK, PEEKW, POKES, VARPTR.

PI(x)
PI times x.  This is more precise for large x.
ex. 10000*#pi contains an error in the least
significant 4 digits, but pi(10000) does not.
The precision depends on the current value of POINT.
(maximum:540 words)
Inp:	number.
Out:	real, complex number.
Ex:	print pi(100)    result: 314.1592...
See:	#pi.

POINT expression
POINT *
Specifies the number of words, n (= 2, 3, ..., 539),
for the decimal part of the variables.  One word is
about 4.8 decimal places;  100 decimal places are 21
words; 1000 decimal places are 208 words.  "POINT *"
sets the largest allowed value.  When multiplications,
divisions, or function calls are involved, n must be no
more than 260, otherwise overflow can occur.  When
complex numbers are involved, n must be no more than
130.
This statement closes all the files, so it must be
placed at the beginning of the program.  Do not use
this statement inside a subroutine or a function, or
when variables are already assigned non-integer values.
No message is displayed if negative n is specified.
PRINT POINT displays the current POINT value.

Stores a byte value at the specified address.
Note:	The segment must be specified by DEFSEG.
See:	DEFSEG, PEEK, POKEW, POKES, VARPTR.

Stores a word value at the specified address.
Note:	The segment must be specified by DEFSEG.
See:	DEFSEG, PEEK, POKEW, POKES, VARPTR.

Stores a string at the specified address.
Note:	The segment must be specified by DEFSEG.
Ex:	defseg=0x8000:A="ABC":pokes 0,A
stores 0x41,0x42,0x43 at the addresses 8000:0001,
0002,0003, respectively, where '0x...' indicates a
See:	DEFSEG, PEEK, POKEW, POKES, VARPTR.

POLY(coeff0,coeff1,coeff2,...)
A polynomial with the arguments as coefficients.
Ex:	A=poly(1,2,3):print A    result: 3*X^2 + 2*X + 1
See:	COEFF, CCOEFF, LCOEFF.

POSX
The x-coordinate of the current cursor position.
(0 <= POSX <= 79)
Ex:	locate posx-1
moves the cursor 1 column to the left.

POSY
The y-coordinate of the current cursor position.
(0 <= POSY <= 24)
Ex:	locate posy-1
moves the cursor up 1 line.

PRINT expression or "string" or CHR(n) or etc.
Outputs the value of the expression, the string, the
character whose ASCII code is n, or the current time to
the screen. "PRINT A;B" prints the values without
spaces in between.  "PRINT A,B" prints the value of B
on the next 8-character field.  Press Control-S for
halt/restart toggle.
See:	LOCATE, ALEN, USING.

PRINT = PRINT + LPRINT + "filename"
Redirects the output of PRINT statements.
"PRINT = PRINT" cancels the redirection.
Note:	No more than one file is allowed on the right-hand
side.
The file must be distinct from the one specified by the
"LPRINT = ..." construct.
The output is redirected to NUL if nothing is on the
right-hand side.
See:	LPRINT =

PRINT #n,expression
PRINTs to file #n.
Note:	Multiple expressions can be output with one PRINT #
statement.
Expressions must be marked off with ";" or ",".
See:	OPEN.

PRM(n)
n-th prime number.  PRM(12251) is the greatest prime
less than (2 to the 17th).
Inp:	integer n (0 <= n <= 12251).
Out:	integer.
Ex:	(prm(0)=1), prm(1)=2, prm(2)=3, ... prm(12251)=131071

PRMDIV(n)
The least prime divisor of n.  It returns 0 if n is
greater than 2^34 and has no divisor less than 2^17.
Inp:	integer.
Out:	integer.
Ex:	print prmdiv(105)    result: 3

PSET (x,y),c
Put a color c to a point (x,y).

PUT (x,y)=A
Puts a graphic pattern in a variable A to (x,y).
See:	GET.

RANDOMIZE [n]
Initializes the random number generator with n.
(0 <= n <= 65535)
Note:	To get a random number, use RND or IRND.
The current time is used if no n is given.
See:	RND, IRND.

RE(x)
Real part of x.
Inp:	number.
Out:	number.
Ex:	print re(123+456#i)    result: 123
See:	CONJ, IM.

Ex:	 10	restore 100
30	print a;b;c
40	end
100	data 11,22,33
result: 11 22 33
See:	DATA, RESTORE.

REDUCE variable1,variable2
Divides two integer variables by their greatest common
divisor.
Note:	The numerator and denominator of a rational number can
be REDUCEd.
Variable2 becomes positive.
Inp:	integer.
See:	GCD.

REM or '
Causes the rest of the line to be ignored.
Note:	REM can be replaced by "'".
Note that a continued line is not ignored.
Ex:	10	print 1:'test:print 2

In the above line "print 2" is not executed.
However in the following lines it is executed:

10	print 1:'test
20	:print 2

RENAME "old filename" to "new filename"
Changes filename.
If the extension is not specified, it is regarded as
".UB".

RENUM [start_of_new_line_numbers] [,start_of_old_line_numbers]
Renumbers the lines with increments of 10.  The new

REPEAT statements UNTIL expression
Repeats  until  is nonzero.
Note:	":" between REPEAT and statements can be omitted.
It can be omitted also between statements and UNTIL.
You may jump out of the loop using GOTO.

RES
Residue (remainder) of the most recent integer division
including division of complex numbers with integer
components and division of polynomials.
Note:	Noninteger divisions and function evaluations can
destroy RES.
Assign it to a variable if you do not use it
immediately after the integer division.
Evaluation of ISQRT(x) (when x is an integer) sets RES
to x - ISQRT(x)^2, which is zero if x is a square
number.
Ex:	A=35:A1=A\10:A0=res
assigns 3 to A1 and 5 to A0.
Out:	integer, complex number, polynomial.

RESTORE line_number or label
statements below the specified line.

RESTORE #n
Equivalent to "CLOSE #n: OPEN #n".
See:	EOF, OPEN.

RETURN
Returns from the subroutine.
See:	GOSUB.

RETURN(return_value)
Returns from the subroutine with a return value.
See:	FN.

REVIVE
Undeletes the program just NEWed.
See:	NEW.

RIGHT(string[,n])
n characters at the right end of a string.
It returns one character when n is not given.
See:	LEFT, MID.

RIGHT(packet[,n])
Packet which contains n members at the right end of
specified packet.
Note:	Returns a packet with one member when n is not given.
Use MEMBER to get a member itself.
See:	MEMBER, LEFT, MID, PACK.

RND
Real-valued random number between 0 and 1.
The precision is determined by the current POINT.
To change the sequence, use RANDOMIZE.
Out:	decimal number x (0 <= x < 1).
Ex:	10	randomize
20	for I=1 to 100
30	  print rnd;
40	next
displays 100 random numbers.
See:	RANDOMIZE, IRND.
appendix B for the algorithm.

ROLL [y][,x]
Scrolls a view area with y dots up and x dots left.

ROUND(x)
Integer nearest to x.
Inp:	integer, real, rational.
Out:	integer.
Ex:	round(1.3)=1,round(-1.7)=-2,round(0.5)=1,round(-0.5)=-1
See:	CEIL, FIX, FLOOR, INT.

RUN ["program_name"]
When a program name is not given, a list of programs is
displayed so that you may select a program using arrow
keys and <Enter>.

SAVE "program_name"
Stores the current program on to a disk in
intermediate-code form.
Note:	If no file name is given(only with "), the current day and
time are used as the program name.
Use ASAVE to save a program in text-file form.

SCREEN n[,activeplane][,displayplane]

Changes a graphic screen mode and initializes graphics.

n= 20 : 640*480 mono color mode.
23 : 640*480 16 color mode.
820 : 800*600 mono color mode.
823 : 800*600 16 color mode.
Activeplane and displayplane are available only on
the mono color mode.  Set the bits corrsponding to the
target planes.

SET "filename","P"
SET "filename"," "
Sets and resets the write protection flag of the file,
respectively.
A data file's filename requires a "+" after it.
Note:	The extension is regarded as ".UB" if not given
To specify a file with no extension, add "." to the
filename.
See:	DIR, KILL.

SFT(x,b)
x is shifted left (or right if b < 0) by b bits.
SFT(x, 1) = x * 2,  SFT(1, -1) = 0,  SFT(1.0, -1) = 0.5.
Inp:	x is an integer or a real, b is an integer.
Out:	same type as x.
Ex:	print sft(123,1)	result: 246
print sft(123.0,1)	result: 246.0
print sft(123,-1)	result: 61
print sft(123.0,-1)	result: 61.5

SGN(x)
1, 0, -1 for x > 0, x = 0, x < 0, respectively.
Inp:	integer, real, rational.
Out:	integer (-1, 0, 1).

SIN(x)
Sine of x.
Inp:	number.
Out:	number.
Ex:	print sin(1.23)    result: 0.9424...
See:	COS, TAN, ASIN.
appendix B for the algorithm.

SINH(x)
Hyperbolic sine of x.
(exp(x)-exp(-x))/2.
Inp:	number.
Out:	number.
Ex:	print sinh(1.23)    result: 1.5644...
See:	COSH.
appendix B for the algorithm.

SKIP
See:	TRON.

SPC(n)
Equivalent to n blanks.  Use with PRINT or LPRINT.
Inp:	integer.
Out:	string.
Ex:	print spc(20);
displays 20 blanks.
See:	LOCATE, LLOCATE, TAB.

SQRT(x)
Square root of x.  SQRT(2) = SQRT(2.0) = 1.4142....
If x is not a nonnegative real number then the solution
which has nonnegative real part is given.
SQRT(4) is 2.0 not 2 (same value but different type).
Inp:	number.
Out:	number.
Ex:	Both sqrt(2) and sqrt(2.0) are 1.4142....
See:	ISQRT, MODSQRT.
appendix B for the algorithm.

STEP
See:	FOR.

STOP
1) Stops running.
Note:	Program halts at a STOP statement.  Control-C also
halts the execution.  The execution can be continued by
CONT.
However, CONT may not work if non-syntax errors have
occurred while the program is halted.  Changing the
values of variables affects the results after the
execution is CONTinued.
Be careful also about the value of RES.

2) Stops tracing.
Note:	When STOP is used with TRON, the program halts before
the execution of each line.
See:	TRON.

3) Changes ctrl+c mode
Note:	STOP 0 disables the break of program execution by ctrl+c.
STOP 1 enables it.
When one changes the mode to disable, one must restore
the mode to enable at the end of the program.

STR(n)
Decimal expression of n.
Inp:	number.
Out:	string.
Ex:	A=1+#i:print right(str(A),3)    result:+#i

1) STRINPUT ["message"] variable
Inputs a string from the keyboard to the specified
variable.
Note:	Unlike INPUT, the string must not be put between "".
Do not delete the prompt "?".  If it is deleted,
add "?" at the beginning of the string.
When only <Enter> is hit, INPUT prompts you to
re-enter, but STRINPUT assigns a null string.
See:	INPUT.

2) STRINPUT = "filename"
Redirects the input to the specified ASCII file.
STRINPUT = STRINPUT cancels the redirection.
See:	INPUT.

SWAP var1,var2
Swaps the contents of the two variables of the same
type.
Ex:	A=1:B=2:swap A,B:print A;B    result: 2 1

SWAP BLOCK array1(index, index, ...), [BLOCK] array2(index,
index, ...)
Swaps the contents of the two arrays of the same type.
Note:	It swaps all the members if the indices are not
specified.
The number of specified members must be the same but
the composition may vary.
If overlapping areas of one array are specified, double
exchanging occurs and results are unpredictable.
Ex:	swap block A(0..9),block B(1..10)
swaps A(0) ... A(9) with B(1) ... B(10).
swap block A(2,1..3),block B(2..4)
swaps A(2,1),A(2,2),A(2,3) with B(2),B(3),B(4).
See:	BLOCK.

SYSTEM
Exit UBASIC and returns to DOS.

TAB(n)
Specifies the column for PRINT and LPRINT.  It is
ignored when absolute value of n is less than the
current column position on the screen.
Note:	It outputs blanks between the current cursor position
and the specified x-coordinate.  It just moves the
cursor if n is negative.
Inp:	integer.
Out:	none.
See:	LOCATE, LLOCATE.

TAN(x)
Tangent of x.
Inp:	number.
Out:	number.
Ex:	print tan(1.23)    result: 2.8198...
See:	COS, SIN, ATAN.
appendix B for the algorithm.

THEN
See:	IF.

CLR TIME
CLR TIME sets the time to 00:00:00 and TIME1000 to 0.

TIME
Inp:	none.
Out:	string.
Ex:	print TIME displays the current time.
See:	TIME1000.

TIME1000
Gives the current time by milli-seconds.
Inp:	none.
Out:	integer.
Ex:	10   clr time
20   gosub *A
30   print time1000
measures an execution time of *A.
See:	TIME

TO
See:	FOR, RENAME.

TROFF
Cancels TRON.
You may restart the program by CONT or TRON.

TRON [STOP] [SKIP]
Displays each line number before execution.  If STOP is
specified, the line number is displayed, and the
program is halted until <Enter> is pressed.  If SKIP is
specified, deeper subroutine calls are not traced.
TRONs and TROFFs may be specified in the program to
debug a portion of the program.  Tracing may be
hindered by a GOTO, GOSUB or a preceding FOR, WHILE or
REPEAT.  For example,
line 20 of the following program may not be traced.

10	for I=0 to 10
20	  print I
30	next

If line 20 is not traced, rewrite it as

20 nop: print I

Note:	Any statement which does not modify the program may be
executed while the program is halted.
You may place TRON and TROFF in the middle of the
program to check the specified part.
Ex:	10	gosub *A
20	end
30	*A
40	  tron skip
50	  gosub *B
60	return
70	*B
80	  print "now in line 80"
90	return
result:
\$	50 now in line 80
\$	60 \$	20
OK
(*B is not traced.)

TYPE(argument)
Type of the argument.
Integer=1, rational=2, real=3, complex number=4, string=5,
packet=6, polynomial=7, mod polynomial=8.
See:	ATTRIB.

UNTIL
See:	REPEAT.

UPPER(string)
Translates characters to uppercase.
Inp:	string.
Out:	string.
Ex:	print upper("This is a pen.")    result:THIS IS A PEN.
See:	LOWER.

USEEMA
Declares the use of EMA-arrays.
Note:	Do not put a space between USE and EMA.
See:	EMA-array.

USING
PRINT USING(x, y), expression
LPRINT USING(x, y), expression
The parameters x and y specify the numbers of digits
for the integer and fractional parts to be output,
respectively.
The output is rounded.
Sign is included in the integer part.
Ex:	print using(3, 2), 9.999
result: 10.00
print using(3, 5),1.234567
result: 1.23457
Note:	Do not put a space between "using" and "(", or
"using" will be regarded as the name of variable.

VAL(string)
Value expressed by the specified string.
Note:	The argument may be a function or a variable.
It is recommended that the string should be ENCODEd
when the same string is being specified several times.
Inp:	string.
Out:	number, string.
Ex:	X=2:print val("X+X^2")    result: 6
See:	DECODE, ENCODE, EVAL.

VAL(polynomial,x)
Value of the polynomial as evaluated for the given x.
Inp:	x is a number or a polynomial.
Out:	number, polynomial.
Ex:	A=poly(0,1,1):print val(A,2)    result: 6

VAL(modpolynomial,x)
Value of the polynomial modulo a prime as evaluated for
the given x.
Inp:	x is an integer.
Out:	integer.
Ex:	modulus=5:A=poly(0,1,1):print val(A,2)    result: 1

VARPTR(variable)
Note:	It returns a 32 bit value.  The upper 16 bits are the
segment address while the lower 16 bits are the offset
See:	DEFSEG, PEEK, POKE.

VCHG [start_line_number or label ,] old_var_name to new_var_name
Replaces variable or array names from the specified
line to the end of the program.
Note:	Ordinary variables cannot be changed into arrays, or
vice versa.
Arrays cannot be specified with indices.
"vchg ABCD to ABcd" does not change the name as "ABCD"
and "Abcd" are regarded as the same.  In this case,
execute "vchg ABCD to AAAA" and "vchg AAAA to ABcd" for
example.
Ex:	VCHG A to A#	VCHG A% to B#	VCHG A() to B#()
The following usages are invalid:
VCHG A to A()  VCHG A() to A	VCHG A(1) to B(1)
See:	VXREF

VIEW (x1,y1)-(x2,y2)[,paintcolor][,boundarycolor]
Limits the graphic area.

VLIST [line_number1 or label1][-line_number2 or label2]
Displays/prints the list of variables.
See:	LVLIST.

VXREF [variable]
Displays/prints the cross-reference list for all (or
the specified) variables.  Array names must be followed
by a (.  APPEND, VLIST, VXREF and VCHG are introduced
to facilitate modular coding in the framework of
BASIC.  LOAD the first module and APPEND the next.
Then use VXREF to see if variable names coincide, in
which case use VCHG to change the names.
See:	LVXREF.

WEND
See:	WHILE.

WHILE expression statements WEND
Executes  while  is nonzero.
Note:	You may jump out of the loop using GOTO.
Ex:	10	A=input\$(1)
20	while and{A<>"N",A<>"n"}
30	  print A;
40	  A=input\$(1)
50	wend
inputs a character from the keyboard and displays
it until "N" or "n" is entered.

WIDTH
Do not use.  See CONSOLE.
>WIDTH 80,number_of_lines
>	Specifies the number of lines displayed in the text
>	screen.
>Note:	The number_of_lines must be 20 or 25.
>	The number of characters in one line is fixed at 80.

WINDOW (x1,y1)-(x2,y2)
Assigns word coordinates to the view area.
Ex:	10   view (100,150)-(200,250)
20   window (-1.0,-0.5)-(0.5,1.0)
After do these, (100,150) corresponds to (-1.0,-0.5)
and (200,250) corresponds to (0.5,1.0).

WORD expression
WORD *
Specifies the length (in words) of a long variable.
Note:	The maximum length is 540 words unless the system
notifies otherwise (when the memory is scarce).  WORD
also closes all open files and clears the variables
except simple short ones.  WORD does not change
execution speed because calculations are always done in
540 words.
WORD must be placed at the beginning of the program.
"WORD *" specifies the maximum length allowed.
A confirmation message is displayed if a positive value
is specified.  No message is displayed if a negative value
is specified.
PRINT WORD displays the current value set by WORD.
WORD cannot be used in subroutines/functions.

open ...  as ... WORD
Specifies the length (in words) of a member of an
external array.
See:	OPEN.

XREF [line_number or label_1] [-line_number or label_2]
Displays/prints the line numbers of the lines that
reference the specified lines (or all the lines).
Press Control-S to halt, Control-C to quit.
See:	LXREF.

Lesson 1.

To display a message, write
print "test"
Here  means 'hit RETURN key'
Then it will be displayed as
test
OK
Next, try the calculation
print 123*456
will result in
56088
OK

Now let's make a program.  The easiest program may be
10   print "This is the 1st program."
It is stored and is waiting for the execution command.
Write
run
then the program will run and it will display:
This is the 1st program.
OK

Lesson 2.

We will make a longer program.
Compute the sum from 1 to 100.

10   Sum=0
20   for I=1 to 100
30     Sum=Sum+I
40   next I
50   print Sum

The 'for' in the line 20 and the 'next' in line 40 are
connected and force the repetition of the commands between
them.
Let's write
run
then the result
5050
OK
will be shown.

Lesson 3.	Big Number Arithmetic

Lessons 1 and 2  can be done by any other computer language.
UBASIC86 can handle very big numbers.  For example, let's compute
the product from 1 to 100.

10   Product=1
20   for I=1 to 100
30     Product=Product*I
40   next
50   print Product
run
93326215443944152681699238856266700490715968264381621468592963
895217599993229915608941463976156518286253697920827223758251185
210916864000000000000000000000000
OK
If one wants to calculate this by usual BASIC language, one
must make a long and complicated program.

Lesson 4.	User Defined Functions

Compute a sum of powers, namely
1^3+2^3+...+100^3 or 11^4+12^4+...+50^4  etc.
Write the power by 'Power', the start number by 'Start' and
the final number by 'Final', then the program may be

10   Power=3:Start=1:Final=20
20   Sum=0
30   for I=Start to Final
40     Sum=Sum+I^Power
50   next
60   print Sum
Let's execute this.  1^3 + 2^3 + ... + 20^3 will be
computed and the result will be displayed:
run
44100
OK
We transform it into a function to reusable.

5   fnPowerSum(Power,Start,Final)
10     local Sum,I
20     Sum=0
30     for I=Start to Final
40       Sum=Sum+I^Power
50     next
60   return(Sum)

Rewrite the lines 10 and 60, and add the line 5.  The
returned value is given as the argument of RETURN.

Now we got our function PowerSum.
To try it, write
print fnPowerSum(22,1,100)
then  1^22 + 2^22 + ... + 100^22  will be computed and the
result is

486614659739941950597622922368810419475443850
OK
We can use user-functions from the direct mode if it is in
the memory.
Store this to the disk.
save "PowerSum"
OK
Exit from UBASIC86 is done by.
system
This will return us to MS-DOS.

Imagine that some days later you need to compute the sum of
the 1-st, 2-nd,... 10-th powers of from 1 to 100.  Since you
already have the function PowerSum, you can easily complete the
work like this:
Write the main program as follows:

10   for I=1 to 10
20     print I,fnPowerSum(I,1,100)
30   next
40   end
Now we use the 'append' command.
append "PowerSum"
OK
Then the 'PowerSum' function is loaded from the disk and
linked to the last of the main program like this:

list
10   for I=1 to 10
20     print I,fnPowerSum(I,1,100)
30   next
40   end
1040   fnPowerSum(Power,Start,Final)
1050     local Sum,I
1060     Sum=0
1070     for I=Start to Final
1080       Sum=Sum+I^Power
1090     next
1100   return(Sum)
OK
Please note that the line numbers are automatically
renumbered.  You need not care about the line numbers.

run
1       5050
2       338350
3       25502500
4       2050333330
5       171708332500
6       14790714119050
7       1300583304167500
8       116177773111333330
9       10507499300049998500
10      959924142434241924250
OK

One who is familiar with some kind of BASIC languages will
be confused by the usage of the variable 'I'.  Some BASICs
will run abnormally by such a program.  But UBASIC86 has local
variables, the 'local' command in line 1050 preserves the value
of 'I' in the main program and generates a new 'I' and
initializes it to 0.  The 'return' command will reset the
original value to 'I'.

Lesson 5.	Calculation of Real numbers

To use real numbers, one must set the precision by the
'POINT' command.
point numerical_expression
is the command format.  The number of decimal digits used is
about 4.8 times the value of the numeric expression.

point 10
will set the precision to 48 decimal digits.
OK
print 11/12
0.916666666666666666666666666666666666666666666666
OK

Calculate sin(X) from  X=1degree,...,45degrees by 20 decimals.
Let's take POINT to be 5.

10   point 5
20   for I=0 to 45
30     X=pi(I/180):'            pi(I/180)=#pi*I/180
40     print using(3),I;using(2,20),sin(X)
50   next

run
0  0.00000000000000000000
1  0.01745240643728351282
2  0.03489949670250097165
3  0.05233595624294383272
4  0.06975647374412530078
5  0.08715574274765817356
6  0.10452846326765347140
7  0.12186934340514748111
8  0.13917310096006544411
9  0.15643446504023086901
10  0.17364817766693034885
...
OK
Here 'print using(p1,p2)' assigns the display length of
integer and fractional parts.

Lesson 6.	High Precision Arithmetic

Theoretically, (1+1/N)^N converges to 'e' as N goes to
infinity.  Let's see this numerically.

10   point 20
20   N=100:print (1+1/N)^N
30   N=10^10:print (1+1/N)^N
40   N=10^50:print (1+1/N)^N

run
2.704813829421526093267194710807530833677938382781002776890201
049117101514306739279439456014346584
2.718281828323131143949794001297229499885179933883965470815866
244433899270751441490494848853547347
2.718281828459045235360287471352662497757247093625082984984087
392709574135039719662542902843924865
OK
The exact value of 'e' is
? #e
2.718281828459045235360287471352662497757247093699959574966967
627724076630353547594571382178525165
OK
Thus we can see that this sequence converges very slowly but
steadily to 'e'.  Note when you try with larger N's, you must
set POINT to be larger than 1/3 of the decimal digits of  N.

Lesson 7.	Output Redirection

There are two ways to store the calculation results to the
disk.
Here we use one of them, 'output redirection'.

print=print+"file name"

assigns the output device of the print command to CRT and the
file.  For example, let's use the program in the Lesson5.
Write before 'run'
print=print+"sin"
OK
run
OK
Note that this time the disk will work.

print=print
OK
restores the normal mode.

system
DO dir on the DOS prompt
then you will find the file 'sin', and you will be
able to edit it with your editor and print it beautifully.
Variations are:
print=lprint
print=print+lprint+"xyz"
lprint=print
etc.

Lesson 8.	Arithmetic of Complex Numbers

UBASIC86 version 8 can treat complex numbers like real numbers.
The unit of the imaginary number(square root of -1) is
denoted by  #i.
Let's make a function which answers one of the solutions of
The well-known formula tells:

20     local D,Sol
30     D=B^2-4*A*C
40     Sol=(-B+sqrt(D))/(2*A)
50   return(Sol)

-1.0+1.4142135623730950487#i
OK
Here  ?  is the shortened form of 'print' and  .  is that of
'fn'.

Complex numbers can be used for the power arithmetic.  Let's
see what is 'i' to the 'i'-th power?

? #i^#i
0.2078795763507619085
OK
is the answer. Since 'i' is the 'e' to the 'pi'/2*'i'-th power,
'i' to the 'i'-th power must be the 'e' to the  -'pi'/2-th
power.

? exp(-pi(1/2))
0.2078795763507619085
OK
Surely!
(You can use other expressions for exp(-pi(1/2)) such as
exp(-#pi/2), #e^(-pi(1/2)) or #e^(-#pi/2), but I recommend
exp(-pi(1/2)) most.)
Since a power function is multivalued, we must determine what
branch UBASIC86 uses.  First UBASIC86 interprets #i^#i =
exp(log(#i)*#i). And log(#i) = atan(1,0)*#i.  Finally two
variable arctangent takes its value larger than -pi less or
equal to pi.

Lesson 9.	Passing functions as parameters

Suppose you are making a function or a subroutine which is
applicable to various functions or subroutines.  You cannot use
the exact function name in the program.  It may be convenient
to use an abstract function name in your subroutine and get the
exact function name as a parameter from the main routine.
See the following example.  The function fnSimpson defined
in the lines 140-240 gives an integration of the function fnF
from A to B by N steps.  Lines 10-20 show the usage.
You can do this only for user defined functions.  The
built-in functions cannot be passed as parameters.

10   print fnSimpson(&fnA,0,1,1/10^6)
20   print fnSimpson(&fnB,0,1,1/10^6)
30   end
40   '
50   fnA(X)
60   return(1/(1+X^2))
70   '
80   fnB(X)
90   return(sqrt(1-X^2))
100   '
110   'Simpson's Rule (Numerical Integration)
120   ' program from the book:
125   ' S.Moriguchi Suuchi Keisan Jutu (Kyoritu Syuppan)
130   '
140   fnSimpson(&fnF(),X1,X2,E1)
150     local Dy,H,M,N,S0,S1,S2,Y1,Y2
160     N=2:H=(X2-X1)/N
170     S0=fnF(X1)+fnF(X2):S1=fnF(X1+H):S2=0
180     Y1=(S0+4*S1)*H/3
190     repeat
200       N=N*2:H=H/2:S2=S1+S2:S1=0
210       for M=1 to N step 2:S1=S1+fnF(X1+M*H):next
220       Y2=(S0+4*S1+2*S2)*H/3:Dy=Y2-Y1:Y1=Y2
230     until absmax(Dy)

Lesson 10.    Arithmetic of Rational Numbers
UBASIC86 version 8 can treat rational numbers.  Write the
numerator first, next the operator // and the denominator.
For example, 2//3 denotes the rational '2 over 3'.  This is not
the same as 2/3(=0.666...) or 2\3 (=0).
The rational number is stored in the reduced form. For example,
2//4 is stored as 1//2, 3//1 is stored as 3(=integer).
The following program will give the rational approximation of
'e', the error will be smaller than 655536^(-21).

10   'rational calculation of E
20   point 21
30   E#=0:I=1:W#=1
40   while cvr(W#)
50     E#=E#+W#:W#=W#//I:I=I+1
60   wend
70   print num(E#)
80   print "/"
90   print den(E#)
100   print "="
110   print cvr(E#)
120   end

Lesson 11.    Arithmetic of one variable polynomials
UBASIC86 version 8 can treat polynomials of one variable.
For example the polynomial 1+x+2*x^3 is denoted in UBASIC86 by
F#=poly(1,1,0,2)  or
F#=1+_x+2*_x^3    or
F#=poly(1):coeff(F#,1)=1:coeff(F#,3)=2
Either will produce the same result.

The following program will give the differential of the
polynomial.

10   'differential
20   input F#
30   DF#=0
40   for I=1 to deg(F#)
50     coeff(DF#,I-1)=I*coeff(F#,I)
60   next
70   print DF#
80   end

Note:	UBASIC has also a differential function DIFF.

Lesson 12.    Packing multiple data
When you have to treat the data which consists of multiple
sub_data, what do you do?
If you are a user of Pascal, you can use the 'record type' but
you cannot make a function which returns this data type.  If
you are a user of an ANSI C, you can define a function which
returns the 'struct'ured data.  UBASIC86 has no such data
structure but can treat a set of data usually called a 'list'
(in UBASIC86 called a 'pack') and can return that as the value of
the functions.
The following program will give the prime factorization of
natural numbers.

10   'prime factorization
20   input "Integer <= 100000 =";N
30   if N>100000 then beep:goto 20
35   if N=1 then print 1:goto 130
40   W#=fnFactor(N)
50   for I=1 to len(W#)
60     Ww#=member(W#,I)
70     print member(Ww#,1);
80     Power=member(Ww#,2)
90     if Power>1 then print "^";Power;
100     if I

Lesson 13.   Manipulation of strings
You can use almost all commands and functions which are
equipped by the usual BASIC languages such as RIGHT(),MID(),
LEFT(),...
can compute the string if it represents a mathematical formula.
Moreover, you can execute the string if it represents a
UBASIC86 command.
The following program will make a table of the function which
you assigned from the keyboard.

10   'table of a function
20   print "Input a function using x as a variable (ex.
sin(x), x+cos(x),...)"
30   strinput F#
40   F#=encode(F#)
50   for I=0 to 20
60     X=I/20
70     print using(4,4),X,using(4,6),val(F#)
80   next
90   end

List of the 48 provided samples, sorted by alphabetical order.

8QUEEN
Solutions of the Eight Queens Problem.
Sample of recursive subroutine.
ALGBREQN
Algebraic Equation of Integral Coefficients.
ALGEQ
Solve algebraic equations of real coefficients.
APRT-CLE
"APRT-CLE" is the extended version of "APRT-CL",
Primality Test.
See "PrimeTests" section.
BERNOULL
This program finds Bernoulli numbers.
CONFRA
Continued fraction expansion of quadratic irrationals.
DET
Easygoing calculation of a determinant.
DETI
Determinant of integer matrix.
DETR
Determinant of a rational matrix.
ECM
Prime Factorization by Elliptic Curve Method.
See "Factorize" section.
ECMJAC
A variation of Elliptic Curve Method.
ECMX
Prime Factorization by Elliptic Curve Method.
Using a machine language routine.
See "Factorize" section.
EULER
Computation of EULER constant by 1000 digits.
GENSHI
Primitive root modulo P.
See "NumTheory" section.
GENSHIP
Prime primitive root modulo P.
See "NumTheory" section.
GSAMPLE
Graphic sample. Displays x*sin(x) function.
See "Graphics" section.
See PLOT3D in "GraphicSamples" section.
HANOI
Towers of Hanoi.
See HANOIGR in "GraphicSamples" section.
IMAGQF
Class number of imaginary quadratic fields
(by the analytic formula)
See "NumTheory" section.
IMQF
Class numbers of imaginary quadratic fields
(counting points in the fundamental domain)
See "NumTheory" section.
KAIJOU
Factorials.
See "NumTheory" section.
LLL
This program implements the reduction algorithm of
Lenstra, Lenstra,
and Lovasz to obtain a "reduced basis" for a positive
definite real valued bilinear form A(-,-) on Z^n.
LUCAS
Lucas test for Mersenne numbers.
MAILLET
Maillet's determinant.
Sample of calculation of integer determinants.
MAILLET3
Carlitz's version of Maillet's determinant.
Sample of calculation of integer determinants by using
multi-modulo.
MAILLET4
Carlitz's version of Maillet's determinant.
Sample of calculation of integer determinants by using
multi-modulo.
Using a machine language routine.
MINPOL
fnMinPol(x,n) computes minimal polynomial of degree n
for x.
This version uses extended memory.
MINPOL1
fnMinPol(x,n) computes minimal polynomial of degree n
for x.
This version uses ordinary memory.
MPQSX
Prime Factorization by MPQS.
Non using disk drives.
MPQSX3
Prime Factorization by MPQS.
Using disk drives.  Powerful up to 70digit.
PI
Computation of PI (10 to 2500 digits).
POLFACT
Polynomial Factorization in Z and Q.
See "Factorize" section.
POLFACT1
Polynomial factorization modulo a prime.
Gives only a decomposition type.
See "Factorize" section.
POLFACT2
Polynomial factorization modulo a prime.
Gives irreducible factors explicitly.
See "Factorize" section.
PPMPX
PPMPX is a prime factorization program for the numbers of
over 40 digits, especially for over 80 digits. The
method is PPMPQS (=the double large primes procedure
variation of the multiple polynomial quadratic sieve).
See PPMPXE.DOC (english text) or PPMPXJ.DOC (japanese
text).
See "Factorize" section.
PRTEST1
Lenstra's version.
See "PrimeTests" section.
RATDEP
This program uses the reduction algorithm of Lenstra,
Lenstra, Lovasz (to obtain a "reduced basis" for the
following bilinear form over Z,  (N is a large
parameter): q(a0, ... ,an) =
a2^2+a3^2+...+an^2+N*abs(z0*a0+...+zn*an)^2
REALQF
Fundamental units and class numbers of real quadratic
fields Displays fundamental units as coefficients of
canonical integral basis
See "NumTheory" section.
REALQF3, REALQF4
Real quadratic field: unit and class number
unit is displayed w.r.t. the standard integer base.
REALQF4 uses EMS memories while REALQF3 does not.
See "NumTheory" section.
RHO
Factorization with rho method.
Most simple one without Brent's modification.
Another Rho program is provided with the Malm samples.
RK
Runga Kutta for y'=f(x,y), y(x0)=y0, integrating in N
equal steps from x0 to x.
SIMPSON
Sample of Simpson's integration.
UBH
Make UBHELP.TBL (pointer table).
UNITR2
Fundamental Units of Real Quadratic Fields
coefficients w.r.t standard integer basis.
See "NumTheory" section.
ZETA, ZETA05, ZETA3, ZETAZERO
Riemann Zeta Function by Euler-Maclaurin Formula.
ZETA3 calculates ZETA(3) to 100 places by APERY's formula.
See ZETAREAL in "GraphicSamples" section.

GraphicSamples
List of the 9 provided samples, sorted by alphabetical order.

BIGMAZE
Draw a big maze.
See MAZE sample for a smaller maze.
DIAMOND
Draw a Regular Extended Diamond Ring.
GRAPH
Graphic sample program.
HANOIGR
Tower of Hanoi (graphic version).
See HANOI sample in "StandardSamples" section.
KNIGHTGR
KnightsTour
MAZE
Draw a maze.
See BIGMAZE sample for a bigger maze.
OTHIBM
Othello Game. Five levels, novice to expert.
PLOT3D
3 dimensional function plotting. Draw a graph of
z = f(x,y).
dimensional.
ZETAREAL
Draw modified Riemann zeta on Re=1/2.
functionZeta*theta=real valued for searching zeros of
Riemann zeta.
See ZETA, ZETA05, ZETA3, ZETAZERO samples in "Standard
Samples" section.

MalmSamples
The MALM.DOC file describes all the numerous procedures/
functions written by Donald E. G. Malm. These pieces of code do
not run directly. They need to be used (APPEND) within programs.

That's why five new samples are added, not described in
MALM.DOC, using some of these numerous procedures.
They can be used directly.

TTdvd
Driver program for Tdvd (trial divides),
Lambda (Carmichael's function),
Sigma (sum of divisors),
Tau (number of divisors) procedures.
DLDiosys
Driver program for LDiosys procedure.
Solves linear Diophantine system.
DLDsys
Driver program for LDiosys procedure.
Gets input from a "Bexample.ubd" file.
Solves linear Diophantine system.
TLehmer
Test program for Lehmer procedure.
Lehmer's method of solving x^2=q, mod p.
TstChn
Test program for Chinese remaindering procedure.

Four functions or procedures described in MALM.DOC are not
provided, UBASIC suppplying them directly in the language :
Mobius
See MOEB keyword
NxtPrm
See NXTPRM keyword
Prmdiv
See PRMDIV keyword
Totient
See EUL keyword

PrimeTests
Primality tests and factorization of integers are discussed,
e.g., in

S. S. Wagstaff, Jr. and J. W. Smith:  Methods of Factoring
Large Integers.  Springer Lecture Notes in Mathematics, No.
1240, pp. 281-303

Hideo Wada: Suugaku 38 (1986), pp. 345-350 (in Japanese).

Henri Cohen : A Course in Computational Algebraic Number
Theory, Springer, Graduate Texts in Mathematics 138,
Third corrected printing 1996

Hans Riesel : Prime Numbers and Computer Methods for
Factorization,  Birk hauser, Progress in Mathematics 126,
Second edition 1994

PRTEST1 is an implementation of Lenstra's version of the
Adleman-Pomerance-Rumely primality test algorithm.  It is
faster than simple-minded ones for integers of more than 12 to
13 figures.  A 70-figure number can be tested in an hour.  A
present implementation can handle integers of up to 137 figures.
See

L. M. Adleman, C.Pomerance and R. S. Rumely:
On Distinguishing Prime Numbers from Composite Numbers.
Ann. of Math. 117(1983), pp.173-206.

H. W. Lenstra, Jr.: Primality Testing Algorithm.
Springer Lecture Notes in Mathematics No. 901, pp. 243-257.

Hideo Wada:  Kousoku Jousan Hou to Sosuu Hantei Hou.
Sophia University Mathematics Lecture Note No. 15,
pp. 131-153 (in Japanese).

PRTEST1 follows Wada's presentation (but does not replace his
Condition 2 by Condition 7).

Cohen and Lenstra have improved the algorithm by using Jacobi
sums:

H. Cohen and H. W. Lenstra, Jr.:  Primality Testing and
Jacobi Sums.  Mathematics of Computation 42 (1984), 297-330.

H. Cohen and A. K. Lenstra:  Implementation of a New
Primality Test.  Mathematics of Computation 48 (1987),
103-121.

APRT-CLE implements their algorithm.  It is faster than PRTEST1
and can test numbers of up to 300 figures.

Factorize
ECM, ECMX -- ECM factors integers using the Elliptic Curve
Method.  In a reasonable time, it can handle integers of more
than 200 figures, but with a factor of at most 20 figures.
ECMX, which uses a machine language routine, is faster by a few
per cent.  The original account of the algorithm is given by

H. W. Lenstra, Jr.:  Factoring Integers with Elliptic
Curves.  Annals of Mathematics 126 (1987), 649-673.

The following is handy when implementing the method.

P. L. Montgomery:  Speeding the Pollard and Elliptic Curve
Methods of Factorization.  Mathematics of Computation 48
(1987), 243-264.

MPQSX3 uses the Multiple Polynomial Quadratic Sieve method.
It can factor integers of up to about 60 figures.
Decrease MaxSZ%(=factor base size) on line 10190 if the
program stops.

A 50-figure number takes 4 minutes(Pentium166).  At this size
of the numbers, the computing time will be multiplied by 10 if
the figure increases by 10.  Therefore 60-figure number will
take about 40 minutes(may be 30-60 minutes).

This routine uses machine language.  Its source listing is in
the MPQS#31.ASM file.

See:

R. D. Silverman:  The Multiple Polynomial Quadratic Sieve.
Mathematics of Computation 48 (1987), 329-339.

If you have 32-bit machines with more than 1MBytes extended
memories and 10-100MBytes Hard Disk free area, try PPMPX which
will decompose up to 100 digits.  It will take about 1000 hours
even by PentiumPro200.

MPQS and ECM are the newest and fastest integer factoring
methods.  But they work quite differently.  MPQS is more
predictable but cannot handle large numbers.  It would take
several months to factor a 100-figure number even with a
supercomputer.  ECM is quite fast when the number has a small
factor:  A 100-figure number with factors of no more than 20
figures can be factored in a reasonable time.

If the number has more than 55 figures, use ECM and hope for
luck! There's no way to tell beforehand how long it will take.
For smaller numbers, use MPQS.

Recently a new factorization method was invented, which was
named the Number Field Sieve method.  This method can be
applied only for the special kind of integers until now.
A.K.Lenstra, H.W.Lenstra,Jr., M.S.Manasse and J.M.Pollard:
The number field sieve, in Lecture Notes in Mathematics 1554,
Springer-Verlag.
They decomposed C148 of 2^(2^9)+1 into P49*P99.

POLFACT -- Factorize one variable polynomial in rational
numbers.

POLFACT1, POLFACT2 -- Both decompose a one-variable polynomial
into a product of irreducible ones modulo a prime number.
POLFACT1 reports only the decomposition type and the number of
factors with multiplicities for each degree.  POLFACT2 finds a
complete set of irreducible factors but runs slower.

NumTheory
UNITR2, REALQF, REALQF3 -- UNITR2 computes fundamental units of
real quadratic fields, i.e., solutions of Pell equations.  It
will suffice if class numbers are not needed.  REALQF is a
straightforward implementation of the flowchart in

Sophia University Mathematics Lecture Note No. 10

with an added routine to compute fundamental units.

REALQF,3,4 determines class numbers and fundamental units by

IMAGQF, IMQF -- IMAGQF finds the class numbers of imaginary
quadratic fields analytically as character sums:

110   D=4*N:if N@4=3 then D=D\4
115   H=0
120   for X=1 to D\2
130     H=H+kro(-D,X)
140   next X
150   H=H\(2-kro(-D,2))
160   print "Class Number is  ";H

IMQF counts points in the fundamental region on the complex
plane. It is much faster than IMAGQF.

GENSHI, GENSHIP -- These compute minimum primitive roots and
minimum prime primitive roots modulo P.

10   'GENSHI version 1.4
20   print "primitive root modulo P "
30   '
40   print:input "Input a prime = ";Prm
50   if Prm=0 then end
60   Genshi=fnGenshi(Prm)
70   if Genshi=0 then print "Sorry, we cannot answer":goto 40
80   print Genshi;"is the smallest primitive root MOD";Prm
90   goto 40
100   '
110   fnGenshi(P)
120   local Gen=1,N=P-1,Nw,Div,Sw%
130   if or{P<3,len(P)>32,prmdiv(P)

AppendixA Code of Numbers.

Short Variables -- The most significant bit represents the
sign, and the remaining 15 bits represent the absolute value.
There is no -32768.

Long and EXTRA Variables -- In the least significant word:
0 - 9th bits : number of effective words
10th bit  : multiple data flag
11th bit  : string flag
12th bit  : rational number flag
13th bit  : complex number flag
14th bit  : real number flag
15th bit  : sign
The absolute value begins with the next word.
The actual length is one plus the length specified by WORD;
thus an EXTRA Variable occupies 541 words(and +3 words for the
special work area).

For example, 1.5 is represented as follows when POINT = 2.
4003H, 0000H, 8000H, 0001H
<- less significant	more significant ->

Also , 1.5+2#i is represented as follows.
2006h,4003H, 0000H, 8000H, 0001H, 0001H, 0002H
(1)(2) (3)			 (4)
(1) complex flg on(sign flg and fraction flag must be off)
(2) effective words
(3) start of real part
(4) start of imaginary part

Files -- Numbers in files are formatted as Long and EXTRA
Variables represented as above.
The first 8 words of a file contains various information.

Arrays --
0000H(WORD)	Dimension.
0002H(WORD)	Not Used.
0004H(WORD)	Size of the 1st dimension.
0006H(WORD)	Number of elements per each 1st index.
0008H(WORD)	Size of the 2nd dimension.
000AH(WORD)	Number of elements per each combination of 1st
& 2nd indices
...
001CH(WORD)	Size of the 7th dimension.
001EH(WORD)	Must be 1.

The current version supports only 3 dimensions.

AppendixB
Built-In Functions

Note that divisions are truncated, not rounded.

POWER -- X^Y
If Y is a positive integer, the repeated squaring method is
used.
If Y is a negative integer, (1/X)^(-Y) is calculated as above.
If Y is a real number, it is done as above for the integer
part and for the rest is done by the combination of EXP and
LOG.
If Y is a complex number, EXP(LOG(X)*Y) is calculated.

ISQRT -- Uses Newton's algorithm:  Set t to the argument x.
Then repeat replacing t with (t + x \ t) \ 2 until t does not
decrease.  This gives the integer part of the square root of
x.

SQRT -- Same as above, with \ replaced by /.
If X is negative then calculates the square root of -x and
multiplies #i.
If X is complex(X=A+B*#i) then
if A>=0 then
Real part =sqrt{(abs(X)+A)/2}
Imag part = B/(2*Real part)
else
Imag part =sqrt{(abs(X)-A)/2}
Real part = B/(2*Imag part)

SIN, COS  -- Adds the Taylor series until the summand
vanishes.
The parameter X is reduced in 0<=x<#pi/4 before calculating the
series.
If X is complex(X=A+B*#i) then
sin(X)=sin(A)*cosh(B)+cos(A)*sinh(b)*#i
cos(X)=cos(A)*cosh(B)+sin(A)*sinh(b)*#i

TAN = SIN/COS

ATAN -- sum of {(-1)^n}X^(2n+1)/(2n+1)
The parameter X is reduced to less than 1/8 by using following
formulas:
pi/2-atan(1/X)
atan(X)=atan(1/2)+atan(2X-1/X+2)
atan(X)=atan(1/4)+atan(4X-1/X+4)
atan(X)=atan(1/4)-atan(1-4X/X+4)
UBASIC86 has atan(1/2) and atan(1/4) as system constants.
If X is complex then use
atan(X)=log{(#i-X)/(#i+X)}/2#i

COSH --	(exp(x)+1/exp(x))/2	if Real part of x >= 0
(exp(-x)+1/exp(-x))/2	otherwise.

SINH -- (exp(x)-1/exp(x))/2	if Real part of x >= 0,
-(exp(-x)-1/exp(-x))/2	otherwise.

EXP -- Adds the Taylor series until the summand vanishes for
0<= x 0
= atan(B/A)+pi	if B>=0>A
= atan(B/A)-pi	if A,B<0 .
Thus atan(B,A) takes its value larger than -pi less or equal
to pi.

ABS --- Absolute value of the complex number  z  is by
definition
sqrt(Re(z)^2+Im(z)^2).
To minimize error, we shift-up  z  by POINT words and shift-
down the result when Re(z) and Im(z) are both less than 1,

RND --- Set a = 41a7h, m = 7fffffffh
repeat{
seed = (a*seed) mod m
RND = seed/m
}

IRND --- Set a = 41a7h, m = 7fffffffh
repeat{
seed = (a*seed) mod m
IRND = seed & 7fffh
}

BESSEL --- using simply their power series:
BesselI(k,x)=sum of (x/2)^(2*n+k)/(n!*(n+k)!)
BesselJ(k,x)=sum of (-1)^n*(x/2)^(2*n+k)/(n!*(n+k)!)

UBASIC86 was written by
Prof. Yuji Kida
Department of Mathematics
Rikkyo University
Nishi-Ikebukuro 3, Tokyo 171, JAPAN.
(e-mail: kida@rkmath.rikkyo.ac.jp)

If you find any bug, please inform me at the address above.
Application programs written in UBASIC86 are also welcome.

I welcome your copying and distributing this software,
magnetically or otherwise.

This software is distributed as is.  I disclaim all
warranties, expressed or implied.  I assume no liability for
damages, direct or consequential, which may result from the
use of this software.

Here I express my hearty thanks to the users who told me the
bugs and suggested me the improvements, especially,
Prof.s Shigeki Egami, Mituo Morimoto in Japan, Dr. Frank O'Hara
in England and Prof. Walter Neumann in USA.
This manual was written, translated and revised by
Prof. Yuji Kida,
Prof. Haruhiko Okumura,
Mrs. Yoko Iwase in Japan,
Dr. Frank O'Hara in England and
Prof. Walter Neumann in USA.
Also Prof. Willem L. van der Poel in the Netherlands pointed
out some mistakes.
Christian Boyer in France checked the whole text and gave many
useful suggestions.

This on-line manual system was created by
Prof. Yoichi Koyama in Japan.

Version 8.88.  3rd printing May 24, 1997.
--------------------------------------------------------------

ftp