home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
progmisc
/
asmlib.zip
/
SOLVE.DOC
< prev
next >
Wrap
Text File
|
1992-06-13
|
20KB
|
676 lines
*********************** MATHEMATICAL SOLUTIONS *****************************
ASMLIB's SOLVE subroutines are handy for many number crunching
problems. Most SOLVE subroutines require a math coprocessor. In
subroutines requiring a math coprocessor, the coprocessor must have been
initialized with FINIT or FNINIT before calling the subroutine. See
MathChip in SYSTEM.DOC. Note that the 80x87 math coprocessors do not
understand unsigned integers.
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
C2F: convert degrees Celcius to degrees Fahrenheit
Source: f2c.asm
80x87 required
Call with: ST(0) = degrees Celcius
Returns: ST(0) = degrees Fahrenheit
Uses: ST(0), 80x87 flags
Example:
extrn c2f:proc
.data
c0 dw 100 ; 100 degrees Celcius
f0 dw ? ; going to store degrees Fahrenheit here
.code
.
.
.
fild c0 ; load degrees Celcius into ST(0)
call c2f ; returns degrees Fahrenheit in ST(0)
fistp f0 ; save degrees Fahrenheit and pop the 8087's stack
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
CUBEFITF4: fit a cubic equation to a set of float4 data
CUBEFITF8: fit a cubic equation to a set of float8 data
CUBEFITI2: fit a cubic equation to a set of integer2 data
CUBEFITI4: fit a cubic equation to a set of integer4 data
Source: cubefit.asm
80x87 required
CubeFit subroutines use the Least Squares method to calculate
the a, b, c and d coefficients of the equation
y = a + bx + c(x^2) + d(x^3)
which best fits the given data points. See also QuadFit and
LineFit.
The data series at DS:[BX] consists of n sets of x and y
coordinates.
Call with: DS:[BX] pointing to data series
CX = number of (x,y) points
Returns: ST(0) = a
ST(1) = b
ST(2) = c
ST(3) = d
Uses: entire 80x87 stack
Example:
extrn cubefiti2:proc
.data
points dw 1,6 ; first (x,y) coordinate pair: x0 = 1, y0 = 6
dw 2,17 ; x1 = 2, y1 = 17
dw 5,86 ; x2 = 5, y2 = 86
dw 4,57 ; x3 = 4, y3 = 57
dw 3,34 ; x4 = 3, y4 = 34
n equ ($-points) shr 2 ; number of coordinate pairs (5 in this case)
.code
; program fragment assumes DS:@data
.
.
.
lea bx,points ; point to data series
mov cx,n ; 5 data points
call cubefiti2 ; returns ST(0) = a
; ST(1) = b
; ST(2) = c
; ST(3) = d
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
DEG2RAD: convert degrees of arc to radians
Source: deg2rad.asm
80x87 required
Call with: ST(0) = degrees of arc
Returns: ST(0) = radians
Uses: 80x87 stack - ST(6) and ST(7) are lost
Example:
include asm.inc
extrn deg2rad:proc
.data
deg dw 180 ; dumb example - everyone knows this is pi radians
.code
; program fragment assumes DS:@data
.
.
.
fild deg ; load degrees into ST(0)
call deg2rad ; it comes back with ST(0) = radians
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
F2C: convert degrees Fahrenheit to degrees Celcius
Source: f2c.asm
80x87 required
Call with: ST(0) = degrees Fahrenheit
Returns: ST(0) = degrees Celcius
Uses: ST(0), 80x87 flags
Example:
extrn f2c:proc
.data
f0 dw 212 ; 212 degrees Farenheit
c0 dw ? ; going to store degrees Celcius here
.code
; program fragment assumes DS:@data
.
.
.
fild f0 ; load degrees Fahrenheit into ST(0)
call f2c ; returns degrees Celcius in ST(0)
fistp c0 ; save degrees Celcius and pop the 8087's stack
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FACTORIAL: calculates the factorial of an integer
Source: factori.asm
80x87 required
Call with: AX = signed integer value
Returns: ST(0) = factorial of the integer value
Note: factorials get very large with relatively small integers
Uses: ST(0); coprocessor stack is pushed, ST(7) is lost
Example:
extrn factorial:proc
.code
.
.
.
mov ax,6 ; gonna calculate the factorial of 6
call factorial
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FPRIMEI2: calculate the derivative of a polynomial function
Source: fprimei2.asm
80x87 NOT required
Call with: DS:[SI] pointing to equation coefficients; all coefficients
must be 2-byte signed integers
CX = order of polynomial (i. e., a quadratic function
is a second-order polynomial, so CX = 2)
Returns: nothing
Uses: nothing
Example:
extrn fprimei2:proc
.data
fx dw 2,0,3,2,0,5 ; the function y = 2+3*(x^2)+2*(x^3)+5*(x^5)
.code
; program fragment assumes DS:@data
.
.
.
mov cx,5 ; fifth order polynomial
lea si,fx ; point to f(x) coefficients (2-byte integers)
call fprimei2 ; calculate derivative of the function
; results:
; fx=0, fx+2=6, fx+4=6, fx+6=0, fx+8=25, fx+10=0
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FPRIMEF4: calculate the derivative of a polynomial function
Source: fprimef4.asm (mathchip.asm, i2tof4.asm, mulf4.asm)
80x87 NOT required
Call with: DS:[SI] pointing to equation coefficients; all coefficients
must be float4 values
CX = order of polynomial (i. e., a quadratic function
is a second-order polynomial, so CX = 2)
FPrimeF4 uses the 80x87 if present, or uses ASMLIB's 80x87
emulation subroutines if no 80x87 is in the system. Registerd
ASMLIB users with ASMLIB source code may eliminate the 80x87
emulation code by re-assembling with the NOEM conditional
assembly directive.
Returns: nothing
Uses: nothing
Example:
extrn fprimef4:proc
.data
fx dd 2.2,0.0,3.5,2.0,0.0,5.1
; the function y = 2.2+3.5*(x^2)+2*(x^3)+5.1*(x^5)
.code
; program fragment assumes DS:@data
.
.
.
mov cx,5 ; fifth order polynomial
lea si,fx ; point to f(x) coefficients (float4 values)
call fprimef4 ; calculate derivative of the function
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FVALUE: calculate the future value of a given present value and
equal periodic payments
Source: fvalue.asm (xtothey.asm)
80x87 required
Call with: DS:[SI] pointing to an ASMLIB Financial data structure
(see FINDATA.INC). The pv, n, i, and pmt data must be
current before calling fvalue.
Returns: updates fv in FINDATA data structure; future value also
returned in ST(0)
Uses: 80x87 stack
Evample:
include asm.inc
include findata.inc
extrn fvalue:proc
.data
case1 findata <12,.0525,100.0,10.0,> ; n = 12 periods
; i = .0525 (5.25% interest rate per n)
; present value = 100
; 10 = payment per n period
.code
; program fragment assumes DS:@data
.
.
.
lea si,case1
call fvalue ; calculate future value; update
; fv in case1
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
LINEFITF4: fit a line equation to a series of float4 data points
LINEFITF8: fit a line equation to a series of float8 data points
LINEFITI2: fit a line equation to a series of i2 data points
LINEFITI4: fit a line equation to a series of i4 data points
Source: linefit.asm
80x87 required
LineFit subroutines use the Least Squares method to calculate
the a and b coefficients of the equation
y = a + bx
which best fits the given data points. See also CubeFit
and QuadFit.
The data series at DS:[BX] consists of n sets of x and y
coordinates.
Call with: DS:[BX] pointing to data series
CX = number of (x,y) points
Returns: ST(0) = a
ST(1) = b
ST(2) = Σx
ST(3) = Σxx
ST(4) = Σy
ST(5) = Σxy
Uses: entire 80x87 stack
Example:
extrn linefiti2:proc
.data
points dw 1,5 ; first (x,y) coordinate pair
dw 3,12 ; x1 = 3, y1 = 12
dw 7,24 ; x2 = 7, y2 = 24
dw 5,17 ; x3 = 5, y3 = 17
dw 10,33 ; x4 = 10, y4 = 33
n equ ($-points) shr 2 ; number of coordinate pairs (5 in this case)
.code
; assumes DS:@data
.
.
.
lea bx,points ; point to data series
mov cx,n ; 5 data points
call linefiti2 ; returns a in ST(0) and b in ST(1)
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
NORMF4, NORMF4b: normalize a float4 array
Source: small & medium: normf4.asm (maxf4.asm)
huge: normf4.asm (maxf4.asm, lowDS2hi.asm)
NORMF8, NORMF8b: normalize a float8 array
Source: small & medium: normf8.asm (maxf8.asm)
huge: normf8.asm (maxf8.asm, lowDS2hi.asm)
80x87 required
Call with: ES:[DI] pointing to the numeric array
CX = number of values in the array
ST(0) = number to normalize the array to
normf?b: BX = bytes between data points
normf4 assumes BX = 4, norm f8 assumes BX = 8
NormF4 and NormF8 assume that the maximum value of the data
is greater than zero. I have used these subroutines
to scale data upward or downward, for example, to convert
from raw data to percent-of-maximum data.
Returns: ST(0) = scaling factor
Uses: ST(0); ST(7) and ST(6) are pushed off the coprocessor stack
Example:
extrn normf4:proc
.data
hundred dw 100 ; convert all data to percent-of-peak
.code
.
.
.
mov ax,f4seg ; segment where the values are stored
mov es,ax
mov di,f4ptr ; now ES:[DI] points to the data
mov cx,1488 ; half-hourly data for a month
fild hundred ; make the maximum value 100
call normf4 ; normalize the data
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
NPVALUE: calculate net present value of an uneven cash flow
Source: npvalue.asm (xtothey.asm)
80x87 required
Call with: DS:[SI] pointing to ASMLIB's FINDATA data structure
ES:[BX] pointing to float4 cash flow data
n, i, and fv in FINDATA must be current before calling NPValue,
and there must be at least n cash flows
Returns: updates pv in FINDATA
ST(0) = present value
Uses: 80x87 stack
Example:
include asm.inc
include findata.inc
extrn npvalue:proc
.data
case1 findata <30,.105,,,0.0> ; 30 payments, 10.5% interest, fv = 0.0
payments dd 10 dup (80.0) ; need 30 payments for this example
dd 10 dup (95.0)
dd 10 dup (103.0)
.code
; program fragment assumes DS:@data
.
.
.
push ds
pop es ; ES = DS
assume es:@data
lea bx,payments
lea si,case1
call npvalue
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
PSOLVEF4: solve a polynomial equation for y, given x; float4 equation
coefficients
Source: psolvef4.asm
PSOLVEF8: solve a polynomial equation for y, given x; float8 equation
coefficients
Source: psolvef8.asm
PSOLVEI2: solve a polynomial equation for y, given x; 2-byte integer
equation coefficients
Source: psolvei2.asm
PSOLVEI4: solve a polynomial equation for y, given x; 4-byte integer
equation coefficients
Source: psolvei4.asm
80x87 required for all psolve subroutines
Call with: DS:[SI] pointing to equation coefficients
CX = n (order of the equation, i. e., a quadratic equation
is a second-order polynomial, so CX = 2)
ST(0) = x value
Returns: ST(0) = y value
Uses: most coprocessor registers
Example:
; I want to calculate y for the equation
; y = 12 + 2x + 17(x**2) + 4(x**3)
extrn psolvei2:proc
.data
fx dw 12,2,17,4
n equ 3 ; third-order equation
x dd 0.85
.code
; program fragment assumes DS:@data
.
.
.
lea si,fx ; DS:[SI] points to equation coefficients
mov cx,n ; a third-order polynomial
fld x ; find y given x
call psolvei2 ; returns y in register ST(0)
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
PVALUE: calculate the present value of an even cash flow
Source: pvalue.asm (xtothey.asm)
80x87 required
Call with: DS:[SI] pointing to FINDATA data structure
n, i, pmt and fv must be updated before calling
pvalue.
Returns: updates pv in FINDATA data structure
ST(0) = present value
Uses: 80x87 stack
Example:
include asm.inc
include findata.inc
extrn pvalue:proc
.data
case1 findata <12,.0525,,10.0,0.0> ; n = 12 periods
; i = .0525 (5.25% interest rate per n)
; present value unknown
; payment per n period = 10
; future value = 0
.code
; program fragment assumes DS:@data
.
.
.
lea si,case1
call pvalue ; calculate present value; update
; pv in case1
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
QUADFITF4: fit a quadratic equation to a series of float4 data points
QUADFITF8: fit a quadratic equation to a series of float8 data points
QUADFITI2: fit a quadratic equation to a series of i2 data points
QUADFITI4: fit a quadratic equation to a series of i4 data points
Source: quadfit.asm
80x87 required
QuadFit subroutines use the Least Squares method to calculate
the a, b and c coefficients of the equation
y = a + bx + c(x^2)
which best fits the given data points. See also CubeFit and
LineFit.
The data series at DS:[BX] consists of n sets of x and y
coordinates.
Call with: DS:[BX] pointing to data series
CX = number of (x,y) points
Returns: ST(0) = a
ST(1) = b
ST(2) = c
Uses: entire 80x87 stack
Example:
extrn quadfiti2:proc
.data
points dw 1,6 ; first (x,y) coordinate pair: x0 = 1, y0 = 6
dw 2,17 ; x1 = 2, y1 = 17
dw 5,86 ; x2 = 5, y2 = 86
dw 4,57 ; x3 = 4, y3 = 57
dw 3,34 ; x4 = 3, y4 = 34
n equ ($-points) shr 2 ; number of coordinate pairs (5 in this case)
.code
; assumes DS:@data
.
.
.
lea bx,points ; point to data series
mov cx,n ; 5 data points
call quadfiti2 ; returns a in ST(0), b in ST(1) and c in ST(2)
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
RAD2DEG: convert radians to degrees of arc
Source: rad2deg.asm
80x87 required
Call with: ST(0) = radians
Returns: ST(0) = degrees of arc
Uses: 80x87 stack - ST(6) and ST(7) are lost
Example:
include asm.inc
extrn rad2deg:proc
.data
rad dd 3.14159 ; dumb example - everyone knows this is 180 degrees
.code
; program fragment assumes DS:@data
.
.
.
fld rad ; load radians into ST(0)
call rad2deg ; it comes back with ST(0) = degrees
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
SAMP2POP: convert sample standard deviation to population standard
deviation; used with StdDev subroutines.
Source: samp2pop.asm
80x87 required
Call with: ST(0) = sample standard deviation
CX = n (number of data points)
Returns: ST(0) = population standard deviation
Uses: ST(0); ST(7), ST(6) and ST(5) are lost
Example: see StdDev series subroutines
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
STDDEVF4: calculate standard deviation of a float4 data series
STDDEVF8: calculate standard deviation of a float8 data series
STDDEVI2: calculate standard deviation of an i2 data series
STDDEVI4: calculate standard deviation of an i4 data series
Source: small & medium: stddev.asm
huge: stddev.asm (lowDS2hi.asm)
80x87 required
Call with: ES:[DI] pointing to data series
CX = number of values
Note that integer values are signed integers
Returns: if CF = 1, CX = 0
if CF = 0, ST(0) = standard deviation
The value returned by StdDev subroutines is the sample standard
deviation S; population standard deviation SP is calculated from
sample standard deviation with this formula:
SP = S * SQRT((n - 1) / n)
Uses: CF, coprocessor registers
Example:
extrn stddevf4:proc ; my data series is in float4 format
extrn samp2pop:proc ; I want the result as a
; population standard deviation
.code
.
.
.
; the program has established a series of float4 values, and I need the
; standard deviation of the series
mov es,series_segment
mov bx,series_offset
mov cx,1600 ; a whole bunch of data
call stddevf4 ; ST(0) = sample standard deviation
; the standard deviation returned by StdDev subroutines is the sample
; standard deviation. Use samp2pop to convert to population standard
; deviation
call samp2pop ; ST(0) = population standard deviation
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
XTOTHEY: calculates x to the y power (x^y)
Source: xtothey.asm
80x87 required
Call with: ST(0) = x, ST(1) = y
Returns: ST(0) = x^y, coprocessor stack popped
Uses: coprocessor stack
Example:
extrn xtothey:proc
.data
x dd 17.4
y dd .3
.code
mov ax,@data ; make the x & y data available
mov ds,ax ; normally you would not need to do this
assume ds:@data ; after the startup code unless the program
; has messed with DS
.
.
.
fld y ; ST(0) = exponent
fld x ; ST(0) = x, ST(1) = exponent
call xtothey ; calculate x**y