Pow2 Function |
Unit
QESBPCSMath
Declaration
Function Pow2(const X: Extended): Extended;
Description
Developed by Rory Daulton and used with permission. December 1998.
EOverflow Exception when X >= 16384. (if there was no other FPU error condition, such as underflow or denormal, before entry to this routine)
EInvalidOp Exception on some occasions when EOverflow would be expected, due to some other FPU error condition (such as underflow) before entry to this routine.
NOTES: 1. This routine is faster and more accurate than Power(2, X). It is also faster and more accurate than Exp(X), so if exponentials and logarithms are needed in a program and the base is not important, use Pow2 and Log2 rather than Exp and Ln or even Power(10, X) and Log10.
2. The algorithm used is to scale the power of the fractional part of X, using FPU commands.
3. Although the FPU (Floating Point Unit) is used, the answer is exact for integral X, since the FSCALE FPU command is.
4. The result underflows to zero at a little less than -16445 and is a normal Extended value for -16382 <= X < 16384.
5. The comments in the code assume that the FPU rounding is set to banker's rounding. The code should work for any kind of rounding, but the precise integer and fractional parts of X would vary depending on the rounding.
Implementation
function Pow2 (const X: Extended): Extended; asm fld X // find Round(X) fld st frndint // find _Frac(X) [minimal fractional part of X, between -0.5 and 0.5] fsub st(1),st fxch st(1) // Find 2**_Frac(X) f2xm1 fld1 fadd // Result := 2**_Frac(X) * 2**Round(X) fscale fstp st(1) fwait End; |
|