Category : BASIC Source Code
Archive   : UBAS830.ZIP
Filename : UBHELP.XXX

 
Output of file : UBHELP.XXX contained in archive : UBAS830.ZIP
;
; * UBASIC for IBM-PC version 8.30
; User's manual for UBHELP system

~~RunningUB
Running UBASIC

Insert the UBASIC distribution diskette, then type

UBIBM

on the DOS command line. ( is the large key engraved
"Enter" or "Return" or a bent arrow.) If your machine's
processor is 80386, type

UBIBM32

instead for better performance. To run the example program
"PI.UB" on the distribution diskette, type

LOAD "PI"
RUN

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

1000

Wait a few seconds. Your screen will display 3.14159...
to 1000 decimal places. Type

LIST

to examine the program. Finally, type

SYSTEM

to exit to the DOS.


~~NUMBERS
NUMBERS

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

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

1-2. Rational numbers
UBASIC allows calculations with rational numbers, only the
type of value is limited to integer / integer. Numerator and
denominator are marked off by '//'.

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

Expression 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 542 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
538 words to the integer part. The smallest positive real
number is 65536^(-4), since 1 word is 65536.

1-4. Complex numbers
UBASIC allows calculations with complex numbers as well as
those with real numbers. The maximum allowed size of a
complex number is 541 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 UBASIC 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))}
absadd(z) = 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.

UBASIC 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 smaller memory and can be calculated faster.


~~VARIABLES
VARIABLES

UBASIC has three types of variables:-

1) Short variables, such as A%, Foo_bah% (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_bah (and arrays)
The size of long variables is specified by WORD statement.
It cannot be specified individually.

3) EXTRA variables, such as A#, Foo_bah# (and arrays)
Variables whose size is fixed at 542 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 UBASIC 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 it is. Uppercase and lowercase
letters are not distinguished.

Ex: A, BC, MaximumElement, Maxscore%, Minscore(10)
Abcdefghi and ABCDEFGHIJ 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 can be declared. Array
indices may be as large as 65534. So the size of an array of
short variables of one dimension 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 542 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 542
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 542 words. This is
because UBASIC executes the operation using all the
significant figures and discards the lesssignificant ones
afterwards.

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


~~OPERATIONS
OPERATIONS

3-1. Operators

Comparisons =, >, <, <>, <=, >=
Addition, Subtraction +, -
Multiplication, Division *, /
Integer Division \
Rational Division //
Remainder @
Power ^

3-2. Value of logical expression
In UBASIC, 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 beyond it are omitted.
Integer division returns an integer quotient when both of
the arguments are integers. A real or complex argument
creates an error.
Remainder of integer division is contained by the system
variable RES while remainder of 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. Calclulation 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 interpleted as X^(Y^Z), but it is (X^Y)^Z
in UBASIC.

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.


~~STRINGS
CHARACTER STRINGS

Like ordinary BASIC, UBASIC allows character strings.
However, UBASIC 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.


~~POLYNOMIAL
POLYNOMIALS

UBASIC 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 coeffi-
cients 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 caluculation 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
PACKETS

Sometimes you may prefer to handle multiple data as one.
UBASIC allows assigning multiple values to one variable. We
call this "a packet" (this is usually called "a list" , but
UBASIC'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.

mid( ,2,*) is equivalent to "cdr" in LISP.
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
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

DEL Deletes the character under the cursor.
BS Deletes the character to the left of the
cursor.
INS Toggles insert mode on/off. An underline
cursor is displayed in insert mode.

HOME Moves the cursor to the home position
CLR Clears the screen

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
Control-F: Cursor rightmost
Control-Q: Cursor home(=HOME)

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

Control-V: Insert/Overwrite toggle(=INS)
Underline 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


~~SUBROUTINE
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. UBASIC 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 TURBO
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 120 return(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.

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-arrays
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 indice must be less than 65535.
(from v8.24 : CAN be declared as local variables.)

1) Install the Expanded Memory Manager(satisfying LIM-EMS4.0)
in your DOS.
Usually add a line like :
device = emm.sys
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
20 read N
30 dim ema(0;N-1,N-1)
40 dim ema(1;N-1,N-1)
50 gosub *ReadEma(0)
60 gosub *ReadEma(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
130 gosub *AddEma(0,1)
140 gosub *DispEma(0)
150 end
160 '
170 *ReadEma(A)
180 local I,J
190 for I=0 to N-1
200 for J=0 to N-1
210 read ema(A;I,J)
220 next
230 next
240 return
250 '
260 *AddEma(A,B)
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
ema(?; using your text-editor.
And then enlarge the size of parameters. We think
you will be confused if you will use EMA-arrays from
the beginning.


~~RandomFile
Random Files

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

Limitation:
1 dimensional.

1) make a new file
open "ABC" 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.

2) read/write
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" 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) 150 repeat
160 inc Gen:Nw=N:Sw%=1
170 repeat
180 Div=prmdiv(Nw)
190 repeat:Nw=Nw\Div:until res:Nw=Nw*Div+res
200 if modpow(Gen,N\Div,P)=1 then Sw%=0:Nw=1
210 until Nw=1
220 until Sw%
230 return(Gen)


~~UserProg.
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. Arguments are passed via either variables or
the first 28 elements of the array. The memory map, after the
program is BLOADed and the arguments set (by BLOAD or CALL),
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.
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)
BLOAD "CLR10", CL%()
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.
MASM and LINK are needed.

;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."

UBASIC program is:

10 'addsub
20 'sample for machine language program
30 '
40 dim AddSub%(200) reserve user program area
50 bload "addsub",AddSub%(A,B,C)
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
100 AddSub%(0)=1
110 call AddSub%()
120 print A,B,C
130 end

Assembly program is:

;addsub.asm

include UB.MAC read macro definition file

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

addAB:
@push v1 push 1st parameter to calc_stack
@push v2 2nd
@add add them
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 tranlate this assembly program to
object program. MASM and LINK are needed. For other
assemblers and linkers, rewrite the makeubb.bat file.


~~Redirect
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.


~~AutoExec.
Automatic Execution

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

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

Then type UBIBM keyboard is disabled.

UBASIC86's output cannot be redirected by UBIBM >TEST1.


~~ASC<->BIN
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 encounts the file end.
But don't care.

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


~~Codes
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 -- the least significant 13 bits
(currently only 9 bits) of the least significant word
represent the number of effective word, the next bit is the
complex flag and the next if the fraction flag,and the most
significant bit is the 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 543 words.

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 dimensons.


~~Functions
Built-In Functions

Note that divisions are truncated, not rounded.

POWER -- X^Y
If Y=0 then answer=1. Otherwise if X=0 then answer=0.
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)
UBASIC 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

SINH -- (exp(x)-1/exp(x))/2

EXP -- Adds the Taylor series until the summand vanishes for
0<= x Generally, when x = n*log(2) +- y, (0<=y is calculated as above and is shifted by n bits.
If X is complex(X=A+B*#i) then
exp(X)=exp(A)*(cos(B)+#i*sin(B)).

LOG -- For 1 <= x < 2, let y = (x-1) / (x+1); repeat adding
(2 / (2n+1)) * y ^ (2n+1) to y until the summand vanishes.
For other values of x, first multiply or divide x by 2
repeatedly, then follow the algorithm above, then subtract or
add the suitable multiple of log(2).
If X is complex(X=A+B*#i) then
log(X)=log(abs(X))+#i*atan(B,A).
Where,
atan(B,A) = sgn(B)*pi/2 if A=0
= atan(B/A) if A>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,

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)!)

~~!
!(n)
See: Factorial.

~~_X
_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 strinput "f(x)=";W#

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

~~#EPS
#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
Euler's constant, #euler = 0.5772...
Out: real.

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

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

~~ABSADD
ABSADD(x)
abs(Re(x)) + abs(Im(x)).
Inp: number.
Out: integer, rational, real.
Ex: print absadd(1+2#i) result: 3

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

~~ALEN
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
AND{expression1,expression2, ...}
Logical product.
1 if all the expressions 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

~~APPEND
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 .
See: LOAD, SAVE, VCHG, VLIST, VXREF.

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

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

~~AS
AS
See: OPEN.

~~ASAVE
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 UBASIC
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 give, the current date and time are
used as the program name.
See: SAVE.

~~ASC
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.

~~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: appendix B for the algorithm.

~~ATTRIB
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.

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

~~BEEP
BEEP
Rings the bell.

~~BESSELI
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
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
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: LEN.

~~BLOAD
BLOAD "machine_language_program", short_var([arg1, arg2, ...])
See: the "User Programs" section.
Arguments must be simple variables.

~~BLOCK
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
CALL short_array_name([arg1,arg2,...])
Calls a user machine language program after the arguments
are set.
See: the "User Programs" section.

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

~~CHR
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..'.

~~CLOSE
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
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 UBASIC.
It does not initialize the system clock, so there may be an
error of up to one second.

~~CLS
CLS [n]
Clears the screen.
Inp: none or integer 1.
Note: Clears the text screen.
Ex: 10 console 0,25:cls

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

~~COEFF
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: 3
A=0:coeff(A,3)=2:coeff(A,0)=5:print A result: 2*X^3 + 5.
See: CCOEFF, LCOEFF, POLY.

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

~~COMBI
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
CONJ(x)
Complex conjugate of x.
Inp: number.
Out: number.
Ex: print conj(1+2#i) result: 1-2#i
See: IM, RE.

~~CONT
CONT
See: STOP.

~~CONSOLE
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.

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

~~COSH
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.

~~CUTLSPC
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
CUTSPC(string)
Cuts off all the spaces in a string.
Inp: string.
Out: string.
Ex: print "A":cutspc(" B C") result:ABC

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

~~DATA
DATA expression1[,expression2,...]
Data for READ statements.
Note: A string must be put in " ".
Commands placed after DATA in the same line are
neglected.
See: READ, RESTORE.

~~DATE
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
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
DECODE(ENCODEd_string)
Original string of an ENCODEd string. Tokens are marked
off by a space.
Ex: print decode(encode("x+sin(abc)") result: X + sin( Abc )
See: ENCODE.

~~DEFSEG
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
DEG(polynomial)
Degree of polynomial.
Note: Degree of 0 is defined to be -1.
Ex: A=poly(0,0,1):print deg(A) result: 2
See: LEN.

~~DELETE
DELETE linenumber1 - linenumber2
Deletes the portion of the program.

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

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

~~DIM
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 is 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
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.

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
return to the current directory after moving to some
other directory.

~~DOSCMD
DOSCMD string
Invokes the command.com file to execute a DOS command.
Ex: DOSCMD "dir b:"
temporally transfers control to MS-DOS to execute
'dir b:'. But the display is cleard at once and
control is returned to UBASIC.
In this case, it is recommended that command.com is
re-invoked by DOSCMD "a:\command".
DOSCMD "program name" runs the specified program.
Note: A program using graphic areas may destroy the work area
of UBASIC.
You may destroy the screen #1 of graphic RAM.

~~EDIT
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
ELSE
See: IF.

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

~~EMA
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
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
ENCODE(string)
Converts a string containing an expression or command to
internal codes.
Note: This makes VAL faster.
See: VAL, DECODE.

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

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

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

~~EOF
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
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
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 recommendded only in
programs which have a main menu and branches out of it.
See: GOTO.

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

~~EVAL
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
EVEN(n)
1 if n is even, 0 if odd.
Ex: print even(10),even(11) result: 1 0
See: ODD.

~~EXIST
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 ommited.
Ex: if exist("abc.ubd") then open "abc" for input as #1

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

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

~~FILE
FILE
See: OPEN.

~~FILE1
FILE1(n), FILE2(n), FILE3(n)
Random files declared by OPEN statements.
Special elements:
FILEi(-1) = number of elements
FILEi(-2) = element word size
FILEi(-3) = POINT WORD length
See: Random files.

~~FILE2
FILE2
See: FILE1


~~FILE3
FILE3
See: FILE1


~~FIND
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
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: INT, ROUND.

~~FN
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
function
210 local Z '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
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

which may not exceed 4294967295. If it is zero or negative,
the loop is not 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

~~FREE
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
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 UBASIC and variable areas are frozen.
FREEZE does not save the area of memory used by a
machine-language program that is not in a UBASIC 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
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(49,63) result: 7
print gcd(_x^2-1, _x^2+2*_x+1) result: 2*x + 2

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

~~GOSUB
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
120 return :'main routine if valiables
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
GOTO line_number or label
Goes to the specified line.

~~HEX
HEX(n)
Hexadecimal conversion of n.
Note: Converts the internal expresson 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
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
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 30
Note the following case in which another IF is used in
a branch.

If "print 2" in the above list is replaced by
"if A=25 then print 2.5 else print 2", line 30 becomes
like this:

30 :elseif A<=20 then if A=25 then print 2.5
else print 2 endif

Note that ENDIF must not be omitted. IF - ENDIF should
be regarded as one block separate from other IF
statements.

However it may be proper to arrange it like this:

30 :elseif A<=20 then
35 :if A=25 then print 2.5 else print 2 endif

or like this:

30 :elseif A<=20 then
32 :if A=25 then print 2.5
34 :else print 2
36 :endif

The difference between ELSEIF and ELSE IF:

if a=1 then x=80 elseif a=2 then x=90 else x=100

is equivalent to

if a=1 then x=80 else if a=2 then x=90 else x=100

But when ENDIF is needed in relation to another IF
statement, a difference of structure appears.

In the first case, you just add it at the end:

if a=1 then x=80 elseif a=2 then x=90 else x=100
endif

In the second case, as there are two statements put
together, ENDIF is needed for each of the statement:

if a=1 then x=80 else if a=2 then x=90 else x=100
endif endif

ELSE can end an IF statement. For example:

if A then if B then C else D else E

In this case, the "if B" statement ends before
"else E".

The use of ENDIF as in the following line is
preferable:

if A then if B then C else D endif else E

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

~~INC
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
INKEY
Checks keyboard buffer.
Note: Character in the keyboard buffer if there is any, null
string otherwise.
Out: character.
Ex: 10 while not inkey
20 gosub 100
30 wend
repeats the subroutine beginning at line 100 until
any key is pressed.

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

~~INPUT
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: UBASIC looks for the first "?" on the cursor line
and takes everything after it as input. UBASIC
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 UBASIC interpreter, so
it can include formulae and variable names.
Ex: 10 input "Enter a number:";A
20 print A
See: 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$
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.
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 UBASIC.
This function repeats the function 0ch(7) of MS-DOS
INT21H.

~~INPUT #
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
INSTR([n],string1,string2)
Scans string1 starting from n-th character of string1 for
the occurence 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
INSTR2([n],string1,string2)
Scans string1 starting from n-th character of string1 for
the first occurence 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
INT(x)
The greatest integer not exceeding x.
Inp: integer, real, rational.
Out: integer.
Ex: INT(12345/100) = 123,INT(-12345/100) = -124.
See: FIX(x) and ROUND(x).

~~IRND
IRND
Integer valued random number from -32767 to 32767.
Note: -32768 does not occur. In return, 0 appears twice as
often as others.
Out: integer i (-32767 <= i <= 32767).
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
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
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 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
KILL "filename"
Kills a program or a data file. In the latter case, append
a + just after the filename.
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 data with ".UBD".
To specify a file without extension, add "." to the
filename.
See: SET.

~~KRO
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 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.


~~LCOEFF
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.

~~LDIR
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
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
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).

~~LIST
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
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
LLOCATE n
Sends a carriage return (but not line feed) and n blanks to
the printer.
See: LOCATE.

~~LOAD
LOAD "program_name"
Reads the program into memory. LOADing a programs from
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
and . (hit to quit)
See: APPEND, SAVE.

~~LOCAL
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.
Note: Variables already passed by address using "&" cannot be
initialized by LOCAL.

~~LOCATE
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.

~~LOG
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
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
LOWER(string)
Translates characters to lowercase.
Inp: string.
Out: string.
Ex: print lower("BecauseIt'sTime.")
result:becauseit'stime.
See: UPPER.

~~LPRINT
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: LPRINT may not function when the use of print.sys is
not declared in config.sys in MS-DOS version 3.1 and
later versions.
Place the "print.sys" in the system disket of MS-DOS
and add the "config.sys" the following line (See MS-DOS
manual for details.):
device = print.sys
See: MS-DOS manual for details.


2) LPRINT = PRINT + LPRINT + "filename.UBD"
Redirects the outputs of LPRINT statements to the
screen (PRINT), the printer (LPRINT), a file
("filename.UBD"), 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 extension ".UBD" is
needed by UBASIC's DIR and KILL commands.
The outputs are redirected to NULL if nothing is on
the right-hand side.

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

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

~~LXREF
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.

~~MAX
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
MELT ["filename"]
Melts a FREEZEd program.
Note: Filename should not have an extension as ".ICE" is
automatically added.
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
MEMBER

1) MEMBER(string,n)
n-th member of the specified string.
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.
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.
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
MID
1) MID(string,x,n)
Substring which starts with the x-th character of the
specified string and contains n characters.
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.
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.
Note: If the string is shorter then 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
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
MOB(n)
See: MOEB

~~MODPOW
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

~~MODINV
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

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

~~MODULUS
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: UBASIC allows polynomials whose coefficients are
integers taken modulo a prime number.
Ex: modulus=2:A=5*_X^2+6*_X+7:print A result: 1*X^2 + 1
Note: Do not change the modulus during calculation with
polynomials.

MODULOUS
Current value of modulus.

~~MOEB
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
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
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
NEW
Deletes the current program and variables.
Note: A program NEWed by mistake can be REVIVEd.
See: REVIVE.

~~NOP
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
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
NUM(argument)
Numerator of the argument.
Inp: integer, rational.
Ex: print num(2//3) result: 2
See: DEN.

~~NXTPRM
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
NEXT
See: FOR.

~~ODD
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
ON
See: ERROR.

~~OPEN
OPEN
1) OPEN "filename" FOR INPUT (or OUTPUT or APPEND) 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.
Do not add a + after the filename. 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 named "file_name" is created.
Note: 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, INPUT #, PRINT #.

2) OPEN "filename(with extension)" FOR INPUT (or OUTPUT or
APPEND) AS #n
Opens a file in text-file form(=ASCII form).
Note: 10 files can be OPENed at the same time.
Add "." to specify a filename without extension.
See: CLOSE, EOF, INPUT #, PRINT #.

3) OPEN "filename" AS FILEn(m1) [WORD m2]
Uses files as an external array, where n = 1, 2, 3.
The upper bound for the array index, m1, may be greater
than 65535. The word size of each array element is
m2 (or 8 if not specified). Protected files can be
read, but not written.

Ex: open "filename" as file1(n) [word x]
makes a new file.
open "filename" as file1
opens an existing file.
Note: Filename does not contain an extension as ".ubd" is
automatically added.
See: CLOSE.
"External arrays" for details.

~~OR
OR{expression1,expression2,...}
0 if all the expressions are zero, 1 otherwise.
If one of the argument is nonzero, it returns 1 at once
without evaluating the following expressions.
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

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

~~PACK
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.

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

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

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

~~PI
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:541 words)
Inp: number.
Out: real, complex number.
Ex: print pi(100) result: 314.1592...
See: #pi.

~~POINT
POINT expression
POINT *
Specifies the number of words, n (= 2, 3, ..., 525), 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.

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

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

~~POKES
POKES address,string
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
hexadecimal number.
See: DEFSEG, PEEK, POKEW, POKES, VARPTR.

~~POLY
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.

~~POSX
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
POSY
The y-coordinate of the current cursor position.
(0 <= POSY <= 24)
Ex: locate posy-1
moves the cursor up 1 line.

~~PRINT
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 #
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
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
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

~~RANDOMIZE
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
RE(x)
Real part of x.
Inp: number.
Out: number.
Ex: print re(123+456#i) result: 123
See: CONJ, IM.

~~READ
READ var1 [,var2,...]
Reads from the DATA statements.
Ex: 10 restore 100
20 read a,b,c
30 print a;b;c
40 end
100 data 11,22,33
result: 11 22 33
See: DATA, RESTORE.

~~REDUCE
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
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
RENAME "old filename" to "new filename"
Changes filename.
If the extension is not specified, it is regarded as ".UB".

~~RENUM
RENUM [start_of_new_line_numbers] [,start_of_old_line_numbers]
Renumbers the lines with increments of 10. The new line
numbers start with 10 if not specified.

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

~~RES
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
RESTORE line_number or label
The next READ statement reads from the first DATA
statements below the specified line.
See: DATA, READ.

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

~~RETURN
RETURN
Returns from the subroutine.
See: GOSUB.

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

~~REVIVE
REVIVE
Undeletes the program just NEWed.
See: NEW.

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

~~RIGHT
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
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.

~~ROUND
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: FIX, INT.

~~RUN
RUN ["program_name"]
[Loads and] runs the program.
When a program name is not given, a list of programs is
displayed so that you may select a program using arrow keys
and .

~~SAVE
SAVE "program_name"
Stores the current program on to a disk in intermediate-
code form.
Note: If no file name is given, the current date and time are
used as the program name.
Use ASAVE to save a program in text-file form.
See: APPEND, ASAVE, LOAD.

~~SET
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
(".UBD" when "+" is added).
To specify a file with no extension, add "." to the
filename.
See: DIR, KILL.

~~SFT
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
SGN(x)
1, 0, -1 for x > 0, x = 0, x < 0, respectively.
Inp: integer, real, rational.
Out: integer (-1, 0, 1).

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

~~SINH
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
SKIP
See: TRON

~~SPC
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
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.
appendix B for the algorithm.

~~STEP
STEP
See: FOR.

~~STOP
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 alsoabout 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.

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

~~STRINPUT
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 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
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
specifed.
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
SYSTEM
Returns to DOS.

~~TAB
TAB(n)
Specifies the column for PRINT and LPRINT. It is ignored
when 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
TAN(x)
Tangent of x.
Inp: number.
Out: number.
Ex: print tan(1.23) result: 2.8198...
See: COS, SIN.
appendix B for the algorithm.

~~THEN
THEN
See: IF.

~~TIME
TIME
CLR TIME sets the time to 00:00:00. PRINT TIME displays
the time.

~~TO
TO
See: FOR.

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

~~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 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
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
UNTIL
See: REPEAT.

~~UPPER
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
USEEMA
Declares the use of EMA-arrays.
Note: Do not put a space between USE and EMA.
See: EMA-array.

~~USING
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
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
VARPTR(variable)
Address of the specified variable.
Note: It returns a 32 bit value. The upper 16 bits are the
segment address while the lower 16 bits are the offset
address.
See: DEFSEG, PEEK, POKE.

~~VCHG
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,A# VCHG A%,B# VCHG A(),B#()
The following usages are invalid:
VCHG A,A() VCHG A(),A VCHG A(1),B(1)

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

~~VXREF
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
WEND
See: WHILE.

~~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
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.

~~WORD
WORD expression
WORD *
Specifies the length (in words) of a long variable.
Note: The maximum length is 542 words unless the system
notifies otherwise (when the memory is scarce). WORD
alsocloses all open files and clears the variables
except simple short ones. WORD does not change
execution speed because calculations are always done in
542 words.
WORD must be placed at the beginning of the program.
"WORD *" specifies the maximum length allowed.
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
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.
Lesson 1.

To display message, write
print "test"
Here means 'hit RETURN key'
Then it will be displayed that
test
OK
Next, try a calculation
print 123*456
will induce
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 be displayed that
This is the 1st program.
OK

~~Lesson 2.
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 are forcing to repeat the commands between them.
Let's write
run
then it will be appeared that
5050
OK

~~Lesson 3.
Lesson 3. Big Number Arithmetic

Lessons 1 and 2 can be done by any other computer languages.
UBASIC 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, he
must make a long and complicated program.

~~Lesson 4.
Lesson 4. User Defined Functions

This time 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. Then 1^3 + 2^3 + ... + 20^3 will be
computed and the result will be displayed:
run
44100
OK
We remake it to a function to use again.

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
returning value is assigned by writing in () after 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
Let's exit from UBASIC once.
system
will return us to MS-DOS.

Imagine some days after, 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 the line numbers 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 normal BASIC languages will be
confused by the usage of the variable 'I'. Usual BASIC will
run abnormally by such a program. But UBASIC has local
variables, the 'local' command in line 1050 preserves the value
of 'I' in the main program and generate the new 'I' and
initialize to 0. The 'return' command will reset the original
value to 'I'.

~~Lesson 5.
Lesson 5. Calculation of Real number

To use the real numbers, one must set the precison by the
'point' command.
point numerical_expression
is the command format. About 4.8 times the assigned value is
the decimal digits.

point 10
will set 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
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.
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 slow but
steadily to 'e'. Note when you try with larger N's, set the
point to be larger than 1/3 of the decimal digits of N.

~~Lesson 7.
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 this time the disk will work.

print=print
OK
sets to the normal mode.
Let's return to MS-DOS.

system
A>dir
You will find the file 'sin', you will be able to edit it
with your editor and print it beautifully.
The variation:
print=lprint
print=print+lprint+"xyz"
lprint=print
etc.

~~Lesson 8.
Lesson 8. Arithmetic of Complex Numbers

UBASIC version 8 can treat complex numbers like as 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
a quadratic equation.
The well-known formula tells:

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

? .QuadraEq(1,2,3)
-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
think 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 UBASIC uses. First UBASIC interprets #i^#i =
exp(log(#i)*#i). And log(#i) = atan(1,0)*#i. Finally two
valiable arctangent takes its value larger than -pi less or
equal to pi.

~~Lesson 9.
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-230 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 the user defined functions. The
built_in functions cannot be passed directly.

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) 240 return(Y2)

run
0.7853981628062055473
0.7853977254182970949
OK

Also subroutines can be passed as parameters.

10 gosub *Test(&*A)
20 gosub *Test(&*B)
30 end
40 '
50 *A
60 print "Now in A."
70 return
80 '
90 *B
100 print "Now in B."
110 return
120 '
130 *Test(&*X)
140 gosub *X
150 return

run
Now in A.
Now in B.
OK

~~Lesson 10.
Lesson 10. Arithmetic of Rational Numbers
UBASIC version 8 can treat rational numbers. Write the
numerator 1st, next the operator // and the denominator. For
example, 2//3 denotes '2 over 3'.
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.
Lesson 11. Arithmetic of 1 variable polynomials
UBASIC version 8 can treat polynomials of 1 valiable.
For example the polynomial 1+x+2*x^3 is denoted in UBASIC 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

~~Lesson 12.
Lesson 12. Packing multiple data
When you 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 such data. If you are
a user of an ANSI C, you can define a function which returns
the 'struct'ured data. UBASIC has no such data structure but
can treat a set of data usually called a 'list'(in UBASIC
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
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 110 next
120 print
130 end
140 '
150 fnFactor(N)
160 local P,Pold,E:W#=pack()
170 Pold=prmdiv(N):N=N\Pold:E=1
180 repeat
190 P=prmdiv(N):N=N\P
200 if P=Pold then E=E+1:goto 190
210 W#=W#+pack(pack(Pold,E))
220 Pold=P:E=1
230 until P=1
240 return(W#)

~~Lesson 13.
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(),...
One advantage was added for UBASIC version 8. That is, you
can compute the string if it represents a mathematical formula.
Moreover, you can execute the string if it represents a
UBASIC command.
The following program will make a table of the function which
you assigned from the keybord.

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

~~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).

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-CL 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.

MPQSX uses the Multiple Polynomial Quadratic Sieve method. It
can factor integers of up to about 45 figures. Increase the
multiple of 16 on line 880 as far as the memory allows:

16*30: 40 figures can be factored
16*50: 45 figures can be factored

A 30-figure number takes 4 minutes; 35-figure, 9 minutes;
40-figure, 20 minutes; 45-figure, an hour.

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

See:

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

If you have 32-bit machines(CPU=386DX,386SX,486) with more than
1MBytes extended memories and 10-100MBytes Hard Disk free area,
try MPQSHD in the MPQS32-subdirectory, which will decompose up
to 80 digits(it will take more than 1000hours).

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 (preprint).
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, REALQF2 -- 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

H. Wada: Table of Class Numbers of Real Quadratic Fields.
Sophia University Mathematics Lecture Note No. 10

with an added routine to compute fundamental units. It is much
faster and more reliable than REALQF2.

REALQF2 determines class numbers by an analytic formula. It is
only approximate; the results are rounded to the nearest
integer. When the discriminant is large, increase the POINT
value to cope with error.

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.2
20 print "Primitive Root modulo P"
30 input "Prime = ";P
40 if P<3 then print "Too small":goto 30
50 if P>=65536^2 then print "Too big":goto 30
60 if prmdiv(P)

70 G=2:N=P-1
80 NW=N
90 D=prmdiv(NW)
100 repeat:NW=NW\D:until res:NW=NW*D+res
110 if modpow(G,N\D,P)=1 then inc G:goto 80
120 if NW>1 then goto 90
130 print G;"is the smallest primitive root MOD";P
140 end

KAIJOU (factorial) -- An example program to illustrate UBASIC86's
output formatting.

10 'KAIJOU version 1.1
20 word 510
30 print "Factorials"
40 F=1
50 for N=1 to 20
60 F=F*N
70 print using(5),N;"! =";using(25),F
80 next N
90 end

~~aboutUB
about UBASIC

UBASIC is written by
Prof. Yuji Kida
Department of Mathematics
Rikkyo University
Nishi-Ikebukuro 3, Tokyo 171, JAPAN.
(e-mail: [email protected]
[email protected])

If you find any bug, please inform me at the address above.
Application programs written in UBASIC 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 is written, translated and revised by
Prof. Yuji Kida,
Mr. Haruhiko Okumura,
Mrs. Yoko Iwase in Japan,
Dr. Frank O'Hara in England and
Prof. Walter Neumann in USA.

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

Version 8.30. January 5, 1992.
--------------------------------------------------------------



  3 Responses to “Category : BASIC Source Code
Archive   : UBAS830.ZIP
Filename : UBHELP.XXX

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/