FPU Object Updated: Feb 11, 2008 With some practice and perhaps the help of a manual on FPU function, even the beginning programmer can use the FPU object. In brief, one loads one or more values and uses methods to modify them. A statement as simple as x=FPU.pop retrieves the result. Developers can implement their formulas by using both the conventional and FPU object instructions and compare the results as follows: DEFREAL10 x1,x2 x1=y*cos(z) 'conventional coding FPU.load y: FPU.load z: FPU.cos: FPU.mul: x2=FPU.pop ' alternatively, ' WITH FPU ' .load y: .load z: .cos: .mul ' END WITH: x2=FPU.pop IF x1=x2 THEN PRINT "I coded it right." Now the x2 calculation may appear to be more cumbersome than the x1. Sure, but imagine you are multiplying var y times a million numbers. With the conventional coding for x1, you would be loading var y 999,999 times for nothing. The x2 steps above illustrate that one can load y just once and then proceed through your million values of z. Here is a common example of speed optimization. We have calculated the mean and standard deviation (sd) of a set of numbers D. Now we normalize the data in the array D: FPU.load mean: FPU.load sd for i=1 to n x=D(i): FPU.load x FPU.sub 2: FPU.div 1 'x=(x-mean)/sd D(i)=FPU.pop 'normalized value: D_mean=0; D_sd=1 next i x=FPU.pop: x=FPU.pop 'remove preloaded values Notice the conventional formula (x-mean)/sd would require loading the mean and sd over and over with each iteration 1 to n above. Rather, the FPU Object allows you to load the mean and sd once, and then loop through the data normalizing it. Please keep in mind that a "constant" for a loop as shown above is simply any value that does not change in the loop and thus may be a variable in your code. HotBasic defaults to maximum precision by storing floating literals such as "2.5" with REAL10 precision. However, in loops and extensive calcuations, reading REAL10 values takes more time than reading DOUBLE values. Hence, if speed is a concern and your constant does not require REAL10 precision, save such floating literals as DOUBLE constants: defdbl c2_5 = 2.5 'code fpu.load c2_5: fpu.load x: fpu.mul 1 'x = x * c2_5 x = fpu.pop 'get result The exclusive HotBasic FPU Object differs from conventional coding in several ways. For operations on two operands (specifically ADD, SUB, SUBR, MUL, DIV, DIVR, IADD, ISUB, ISUBR, IMUL, IDIV and IDIVR) the operand loaded first stays on the FPU. E.g, if a matrix is to be multiplied by a constant, that value would have to be loaded just once. Normally, IDIV and IDIVR can result in floating values; however, the FPU Object is coded to produce integer results similar to the "\" operator in conventional coding. E.g., i = a \ b 'is integer divide. Note: "top" refers to ST or ST(0) or last value loaded. PROPERTIES (Read/Write): ~~~~~~~~~~ ~~~~~~~~~~~~~ CONTROL Returns or stores FPU control word. See STATUS examples. STATE Saves or restores coprocesser state to/from a 14 byte buffer. STATUS Returns FPU status word. fpustat=FPU.status Stores FPU status word. FPU.status=fpustat PROPERTIES (Read Only Numeric): ~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ ERROR 0 = no exception. FPU.error returns 7 FPU exception bits which may be examined: invalid operation (&H1), denormalized (&H2), divide by zero (&H4), overflow (&H8), underflow (&H10), precision reduced (&H20), FPU stack fault (&H40). i = FPU.error 'assign to non-float to avoid resetting FPU error flags IF i OR 28 THEN PRINT "zero divide or overflow or underflow" Except where specified, METHODS modify the value at "top" of FPU stack: METHODS Arguments & Comments ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ ABS Absolute value ACOS Arc cosine ADD Add ADD n Add FPU value at index n (1 to 7) ADDP Add FPU values 0 and 1; ; value 0 popped; result at 0 AND Logical AND ASIN Arc sine ATAN,ATN Arc tangent where top = x/y BCDLOAD src Load BCD data from src; src = real10-dimensioned variable. BCDPOP dst dst receives BCD data; dst = real10 variable (10 byte buffer). CHS Change sign COPY Load copy of top value; e.g, .load x: .copy: .mul gives x^2 COS Cosine DIV Divide DIV n Dividy by FPU value at index n (1 to 7) DIVP Divide FPU value 0 by value 1; value 0 popped; result at 0 DIVR Divide reverse operand order EXAM Examine top value and set condition codes in STATUS. EXP Exponential function; e raised to the power of top EXCHANGE n Exchange FPU value n by top, n = 1 to 7; default n = 1 EXTRACT Exponent replaces top; mantissa pushed on to FPU stack. FRAC Fractional part of top replaces top HCOS Hyperbolic cosine HSIN Hyperbolic sine HTAN Hyperbolic tangent IADD Integer add (integer result) IDIV Integer divide (integer result) IDIVR Integer divide reverse operand order (integer result) IMUL Integer multiply (integer result) INIT Initialize FPU unit INT Convert to integer less than or equal to top ISUB Integer subtract (integer result) ISUBR Integer subtract reverse operand order (integer result) LOAD scr Load FPU from scr, any valid numeric data type. LOADENV scr Load FPU environment from scr (94 byte buffer) LN Natural logarithm LNTWO Load natural log of 2 LOG Logarithm base 10 LOG2E Load logarithm base 2 of e LOG2TEN Load logarithm base 2 of 10 LOGTWO Load logarithm base 10 of 2 MUL Multiply MUL n Multiply by FPU value at index n (1 to 7) MULP Multiply FPU values 0 and 1; value 0 popped; result at 0 NAPIER Load napier value e NEG Change sign; same as CHS ONE Load value = 1 OR Logical OR FPU value 1 and top PI Load pi POP Retrieve value and "pop" FPU stack. E.g., x=FPU.pop PREM Partial remainder READ Retrieve value. E.g., x=FPU.read ROUND Convert to integer by round method SAVEENV dst Save FPU environment to dst (94 byte buffer) SCALE Scale by power of 2 SGN Get sign (1,0,-1) of top SIN Sine SINCOS FPU sincos generation SQR Square root SUB Subtract SUB n Subtract FPU value at index n (1 to 7) SUBP Subtract FPU value 1 from 0; value 0 popped; result at 0 SUBR Subtract reverse operand order TAN Tangent TEST Integer compare and pop XOR Logical XOR FPU value 1 and top XEXPY X ^ Y where X is FPU value 1; Y is top YL2X Y * logarithm base 2 of X YL2XP1 Y * logarithm base 2 of (X+1) 2XM1 (2 ^ X) - 1 ZERO Load value of zero ########### hotfpu.bas and hotfpu2.bas show FPU Object coding examples. Copyright 2003-2008 James J Keene PhD Original Publication: Aug 26, 2003