home *** CD-ROM | disk | FTP | other *** search
-
- *********************** 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
-
-