mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
Some folks might think: “you still use RCS”?!? And we will say, hey, at least we switched from SCCS to RCS back in … I think it was around 1994 ... at least we are keeping up! :-) :-) :-) Logs say that SCCS version 18 became RCS version 19 on 1994 March 18. RCS served us well. But now it is time to move on. And so we are switching to git. Calc releases produce a lot of file changes. In the 125 releases of calc since 1996, when I started managing calc releases, there have been 15473 file mods!
220 lines
8.6 KiB
Plaintext
220 lines
8.6 KiB
Plaintext
Using objects
|
|
|
|
Objects are user-defined types which are associated with user-
|
|
defined functions to manipulate them. Object types are defined
|
|
similarly to structures in C, and consist of one or more elements.
|
|
The advantage of an object is that the user-defined routines are
|
|
automatically called by the calculator for various operations,
|
|
such as addition, multiplication, and printing. Thus they can be
|
|
manipulated by the user as if they were just another kind of number.
|
|
|
|
An example object type is "surd", which represents numbers of the form
|
|
|
|
a + b*sqrt(D),
|
|
|
|
where D is a fixed integer, and 'a' and 'b' are arbitrary rational
|
|
numbers. Addition, subtraction, multiplication, and division can be
|
|
performed on such numbers, and the result can be put unambiguously
|
|
into the same form. (Complex numbers are an example of surds, where
|
|
D is -1.)
|
|
|
|
The "obj" statement defines either an object type or an actual
|
|
variable of that type. When defining the object type, the names of
|
|
its elements are specified inside of a pair of braces. To define
|
|
the surd object type, the following could be used:
|
|
|
|
obj surd {a, b};
|
|
|
|
Here a and b are the element names for the two components of the
|
|
surd object. An object type can be defined more than once as long
|
|
as the number of elements and their names are the same.
|
|
|
|
When an object is created, the elements are all defined with zero
|
|
values. A user-defined routine should be provided which will place
|
|
useful values in the elements. For example, for an object of type
|
|
'surd', a function called 'surd' can be defined to set the two
|
|
components as follows:
|
|
|
|
define surd(a, b)
|
|
{
|
|
local x;
|
|
|
|
obj surd x;
|
|
x.a = a;
|
|
x.b = b;
|
|
return x;
|
|
}
|
|
|
|
When an operation is attempted for an object, user functions with
|
|
particular names are automatically called to perform the operation.
|
|
These names are created by concatenating the object type name and
|
|
the operation name together with an underscore. For example, when
|
|
multiplying two objects of type surd, the function "surd_mul" is
|
|
called.
|
|
|
|
The user function is called with the necessary arguments for that
|
|
operation. For example, for "surd_mul", there are two arguments,
|
|
which are the two numbers. The order of the arguments is always
|
|
the order of the binary operands. If only one of the operands to
|
|
a binary operator is an object, then the user function for that
|
|
object type is still called. If the two operands are of different
|
|
object types, then the user function that is called is the one for
|
|
the first operand.
|
|
|
|
The above rules mean that for full generality, user functions
|
|
should detect that one of their arguments is not of its own object
|
|
type by using the 'istype' function, and then handle these cases
|
|
specially. In this way, users can mix normal numbers with object
|
|
types. (Functions which only have one operand don't have to worry
|
|
about this.) The following example of "surd_mul" demonstrates how
|
|
to handle regular numbers when used together with surds:
|
|
|
|
define surd_mul(a, b)
|
|
{
|
|
local x;
|
|
|
|
obj surd x;
|
|
if (!istype(a, x)) {
|
|
/* a not of type surd */
|
|
x.a = b.a * a;
|
|
x.b = b.b * a;
|
|
} else if (!istype(b, x)) {
|
|
/* b not of type surd */
|
|
x.a = a.a * b;
|
|
x.b = a.b * b;
|
|
} else {
|
|
/* both are surds */
|
|
x.a = a.a * b.a + D * a.b * b.b;
|
|
x.b = a.a * b.b + a.b * b.a;
|
|
}
|
|
if (x.b == 0)
|
|
return x.a; /* normal number */
|
|
return x; /* return surd */
|
|
}
|
|
|
|
In order to print the value of an object nicely, a user defined
|
|
routine can be provided. For small amounts of output, the print
|
|
routine should not print a newline. Also, it is most convenient
|
|
if the printed object looks like the call to the creation routine.
|
|
For output to be correctly collected within nested output calls,
|
|
output should only go to stdout. This means use the 'print'
|
|
statement, the 'printf' function, or the 'fprintf' function with
|
|
'files(1)' as the output file. For example, for the "surd" object:
|
|
|
|
define surd_print(a)
|
|
{
|
|
print "surd(" : a.a : "," : a.b : ")" : ;
|
|
}
|
|
|
|
It is not necessary to provide routines for all possible operations
|
|
for an object, if those operations can be defaulted or do not make
|
|
sense for the object. The calculator will attempt meaningful
|
|
defaults for many operations if they are not defined. For example,
|
|
if 'surd_square' is not defined to square a number, then 'surd_mul'
|
|
will be called to perform the squaring. When a default is not
|
|
possible, then an error will be generated.
|
|
|
|
Please note: Arguments to object functions are always passed by
|
|
reference (as if an '&' was specified for each variable in the call).
|
|
Therefore, the function should not modify the parameters, but should
|
|
copy them into local variables before modifying them. This is done
|
|
in order to make object calls quicker in general.
|
|
|
|
The double-bracket operator can be used to reference the elements
|
|
of any object in a generic manner. When this is done, index 0
|
|
corresponds to the first element name, index 1 to the second name,
|
|
and so on. The 'size' function will return the number of elements
|
|
in an object.
|
|
|
|
The following is a list of the operations possible for objects.
|
|
The 'xx' in each function name is replaced with the actual object
|
|
type name. This table is displayed by the 'show objfunctions' command.
|
|
|
|
Name Args Comments
|
|
|
|
xx_print 1 print value, default prints elements
|
|
xx_one 1 multiplicative identity, default is 1
|
|
xx_test 1 logical test (false,true => 0,1),
|
|
default tests elements
|
|
xx_add 2
|
|
xx_sub 2
|
|
xx_neg 1 negative
|
|
xx_mul 2
|
|
xx_div 2 non-integral division
|
|
xx_inv 1 multiplicative inverse
|
|
xx_abs 2 absolute value within given error
|
|
xx_norm 1 square of absolute value
|
|
xx_conj 1 conjugate
|
|
xx_pow 2 integer power, default does multiply,
|
|
square, inverse
|
|
xx_sgn 1 sign of value (-1, 0, 1)
|
|
xx_cmp 2 equality (equal,nonequal => 0,1),
|
|
default tests elements
|
|
xx_rel 2 relative order, positive for >, etc.
|
|
xx_quo 3 integer quotient
|
|
xx_mod 3 remainder of division
|
|
xx_int 1 integer part
|
|
xx_frac 1 fractional part
|
|
xx_inc 1 increment, default adds 1
|
|
xx_dec 1 decrement, default subtracts 1
|
|
xx_square 1 default multiplies by itself
|
|
xx_scale 2 multiply by power of 2
|
|
xx_shift 2 shift left by n bits (right if negative)
|
|
xx_round 3 round to given number of decimal places
|
|
xx_bround 3 round to given number of binary places
|
|
xx_root 3 root of value within given error
|
|
xx_sqrt 3 square root within given error
|
|
xx_or 2 bitwise or
|
|
xx_and 2 bitwise and
|
|
xx_not 1 logical not
|
|
xx_fact 1 factorial or postfix !
|
|
xx_min 1 value for min(...)
|
|
xx_max 1 value for max(...)
|
|
xx_sum 1 value for sum(...)
|
|
xx_assign 2 assign, defaults to a = b
|
|
xx_xor 2 value for binary ~
|
|
xx_comp 1 value for unary ~
|
|
xx_content 1 unary hash op
|
|
xx_hashop 2 binary hash op
|
|
xx_backslash 1 unary backslash op
|
|
xx_setminus 2 binary backslash op
|
|
xx_plus 1 unary + op
|
|
|
|
Also see the standard resource files:
|
|
|
|
deg.cal
|
|
dms.cal
|
|
ellip.cal
|
|
hms.cal
|
|
mod.cal
|
|
natnumset.cal
|
|
poly.cal
|
|
quat.cal
|
|
regress.cal
|
|
set8700.cal
|
|
surd.cal
|
|
test2300.cal
|
|
test3100.cal
|
|
|
|
## Copyright (C) 1999,2010 Landon Curt Noll
|
|
##
|
|
## Calc is open software; you can redistribute it and/or modify it under
|
|
## the terms of the version 2.1 of the GNU Lesser General Public License
|
|
## as published by the Free Software Foundation.
|
|
##
|
|
## Calc is distributed in the hope that it will be useful, but WITHOUT
|
|
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
|
## Public License for more details.
|
|
##
|
|
## A copy of version 2.1 of the GNU Lesser General Public License is
|
|
## distributed with calc under the filename COPYING-LGPL. You should have
|
|
## received a copy with calc; if not, write to Free Software Foundation, Inc.
|
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
##
|
|
## Under source code control: 1991/07/21 04:37:22
|
|
## File existed as early as: 1991
|
|
##
|
|
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
|
|
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|