home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_GEN
/
ASM32.ZIP
/
SOLVE.DOC
< prev
next >
Wrap
Text File
|
1993-09-12
|
22KB
|
777 lines
*********************** MATHEMATICAL SOLUTIONS *****************************
ASM32'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:
include code32.inc
extrn c2f:near
; 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: EBX pointing to data series
ECX = number of (x,y) points
Returns: ST(0) = a
ST(1) = b
ST(2) = c
ST(3) = d
Uses: entire 80x87 stack
Example:
include code32.inc
extrn cubefiti2:near
; 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
.
.
.
lea ebx,points ; point to data series
mov ecx,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 code32 .inc
extrn deg2rad:near
; data
deg dw 180 ; dumb example - everyone knows this is pi radians
; code
.
.
.
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:
include code32.inc
extrn f2c:near
; data
f0 dw 212 ; 212 degrees Farenheit
c0 dw ? ; going to store degrees Celcius here
; code
.
.
.
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: EAX = 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:
include code32.inc
extrn factorial:near
; code
.
.
.
mov eax,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: ESI pointing to equation coefficients; all coefficients
must be 2-byte signed integers
ECX = order of polynomial (i. e., a quadratic function
is a second-order polynomial, so ECX = 2)
ECX limited to 0 < ECX < 32768
Returns: nothing
Uses: nothing
Example:
include code32.inc
extrn fprimei2:near
; data
fx dw 2,0,3,2,0,5 ; the function y = 2+3*(x^2)+2*(x^3)+5*(x^5)
; code
.
.
.
mov ecx,5 ; fifth order polynomial
lea esi,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
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FPRIMEI4: calculate the derivative of a polynomial function
Source: fprimei4.asm
80x87 NOT required
Call with: ESI pointing to equation coefficients; all coefficients
must be 4-byte signed integers
ECX = order of polynomial (i. e., a quadratic function
is a second-order polynomial, so ECX = 2)
ECX limited to 0 < ECX < 32768
Returns: nothing
Uses: nothing
Example:
include code32.inc
extrn fprimei4:near
; data
fx dd 2,0,3,2,0,5 ; the function y = 2+3*(x^2)+2*(x^3)+5*(x^5)
; code
.
.
.
mov ecx,5 ; fifth order polynomial
lea esi,fx ; point to f(x) coefficients (2-byte integers)
call fprimei4 ; 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
80x87 required
Call with: ESI pointing to equation coefficients; all coefficients
must be float4 values
ECX = order of polynomial (i. e., a quadratic function
is a second-order polynomial, so ECX = 2)
0 < ECX < 32768
Returns: nothing
Uses: nothing
Example:
include code32.inc
extrn fprimef4:near
; 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
.
.
.
mov ecx,5 ; fifth order polynomial
lea esi,fx ; point to f(x) coefficients (float4 values)
call fprimef4 ; calculate derivative of the function
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FPRIMEF8: calculate the derivative of a polynomial function
Source: fprimef8.asm
80x87 required
Call with: ESI pointing to equation coefficients; all coefficients
must be float8 values
ECX = order of polynomial (i. e., a quadratic function
is a second-order polynomial, so ECX = 2)
0 < ECX < 32768
Returns: nothing
Uses: nothing
Example:
include code32.inc
extrn fprimef8:near
; data
fx dq 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
.
.
.
mov ecx,5 ; fifth order polynomial
lea esi,fx ; point to f(x) coefficients (float4 values)
call fprimef8 ; 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 ASM32 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:near
.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: EBX pointing to data series
ECX = 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:
include code32.inc
extrn linefiti2:near
; 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
.
.
.
lea ebx,points ; point to data series
mov ecx,n ; 5 data points
call linefiti2 ; returns a in ST(0) and b in ST(1)
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
NORMF4, NORMF4b: normalize a float4 array
Source: normf4.asm (maxf4.asm)
NORMF8, NORMF8b: normalize a float8 array
Source: normf8.asm (maxf8.asm)
80x87 required
Call with: EDI pointing to the numeric array
ECX = number of values in the array
ST(0) = number to normalize the array to
normf?b: EBX = bytes between data points
normf4 assumes EBX = 4, norm f8 assumes EBX = 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:
include code32.inc
extrn normf4:near
; data
hundred dw 100 ; convert all data to percent-of-peak
; code
.
.
.
esi edi,f4fdata ; EDI points to the data
mov ecx,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: ESI pointing to ASM32's FINDATA data structure
EBX 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 code32.inc
include findata.inc
extrn npvalue:near
; 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
.
.
.
lea ebx,payments
lea esi,case1
call npvalue
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
PAYMENT: calculates periodic payment
Source: payment.asm
80x87 required
Call with: ESI pointing to ASM32's FINDATA data structure
n, i, fv and pv in FINDATA must be current before calling
Payment. Payment replaces pmt in the data structure.
Returns: replaces pmt in data structure
Uses: 80x87 stack; 80x86 registers and flags are unchanged
Example:
include code32.inc
include findata.inc
extrn payment:near
; data
; 30 payments, 10.5% interest, pv = 10,000, fv = 0.0
case1 findata <30,.105,10000.0,,0.0>
; code
.
.
.
lea esi,case1
call payment
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
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: ESI pointing to equation coefficients
ECX = n (order of the equation, i. e., a quadratic equation
is a second-order polynomial, so ECX = 2)
ST(0) = x value
Returns: ST(0) = y value
Uses: most coprocessor registers
Example:
include code32.inc
; I want to calculate y for the equation
; y = 12 + 2x + 17(x**2) + 4(x**3)
extrn psolvei2:near
; data
fx dw 12,2,17,4
n equ 3 ; third-order equation
x dd 0.85
; code
.
.
.
lea esi,fx ; DS:[SI] points to equation coefficients
mov ecx,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: ESI] 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 code32.inc
include findata.inc
extrn pvalue:near
; 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
.
.
.
lea esi,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: EBX pointing to data series
ECX = number of (x,y) points
Returns: ST(0) = a
ST(1) = b
ST(2) = c
Uses: entire 80x87 stack
Example:
include code32.inc
extrn quadfiti2:near
; 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
.
.
.
lea ebx,points ; point to data series
mov ecx,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 code32.inc
extrn rad2deg:near
; data
rad dd 3.14159 ; dumb example - everyone knows this is 180 degrees
; code
.
.
.
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
ECX = 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: stddev.asm
80x87 required
Call with: EDI pointing to data series
ECX = number of values
Note that integer values are signed integers
Returns: if CF = 1, was called with ECX = 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:
include code32.inc
extrn stddevf4:near ; my data series is in float4 format
extrn samp2pop:near ; 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
lea edi,series_of_numbers
mov dcx,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:
include code32.inc
extrn xtothey:near
; data
x dd 17.4
y dd .3
; code
.
.
.
fld y ; ST(0) = exponent
fld x ; ST(0) = x, ST(1) = exponent
call xtothey ; calculate x**y