Ingres CL FP
From Ingres Community Wiki
|
Ingres Compatability Library |
Compatibility Library Specification FP
Abstract
This is the specification of the FP facility provided by the compatibility library.
Revision: 1.0, 24-jun-93
Document History
- Revision 1.0, last modified 24-Jun-1993
- Created from MH.
Specification
Introduction
These routines implement mathematical operations. Many of these routines are used to implement the built in mathematical operations of QUEL and SQL.
No Exceptions Allowed
None of the FP functions may signal an exception of any kind.
Finite Numbers
A finite number is any legal floating point number. This excludes infinity and NaN, which are generally represented by special, hardware-dependent floating point bit patterns.
Library
CL
Packed Decimal
See the CV section for information about the packed decimal datatype.
Implementation Suggestions
Test Values First
Rather then setting up expensive and elaborate exception handlers, try testing the input values first to see whether they exceed the maximum values that your machine can handle. For example, if the OS-provided function for computing the exponential of a number cannot handle numbers greater than 88.3, then test the input to FPexp() to ensure that it is less than 88.3 before calling the OS function. This will elimii4e the need to set up an exception handler for this function. Another example would be to test the input to FPsqrt() to ensure that it is positive before calling the OS-provided square root function.
However, certain functions may still generate exceptions even though they are called with reasonable input. For example, while computing the power of one number raised to another number, it would be difficult to determine beforehand whether the operation will overflow or underflow. In these cases, you will need to catch this over/underflow and return the appropriate status from the FP function.
Remember, FP functions are not allowed to signal exceptions.
Header File <fp.h>
The header file <fp.h> must be included before using any of the functions provided.
Executable interface
The following functions are provided.
FPatan -- arctangent
Find the arctangent of x in the range -π/2 to π/2. As x approaches ±∞, if, FPatan returns ±π/2 , respectively.
Returned result is in radians.
Inputs:
| x | Pointer to the number to find the arctangent of. |
Outputs:
| result | Pointer to result. |
Returns:
| OK | if operation succeeded. |
| FP_NOT_FINITE_ARGUMENT | when x is not a finite number. |
Exceptions:
| None |
Definition:
STATUS FPatan( double *x, double *result )
FPceil -- ceiling
Returns the smallest integer not less than the argument passed to it. The return value, although an integer, is returned as an double and may not fit in an integer type.
Inputs:
| x | Pointer to the number to find ceiling for. |
Outputs:
| result | Pointer to result. |
Returns:
| OK | if operation succeeded. |
| FP_NOT_FINITE_ARGUMENT | when x is not a finite number. |
Exceptions:
| None |
Definition:
STATUS FPceil( double *x, double *result )
FPcos -- cosine
Find the cosine of x, where x is in radians.
Inputs:
| x | Pointer to the number of radians to take cosine of. |
Outputs:
| result | Pointer to result. |
Returns:
| OK | if operation succeeded. |
| FP_NOT_FINITE_ARGUMENT | when x is not a finite number. |
Exceptions:
| None |
Definition:
STATUS FPcos( double *x, double *result )
FPdfinite -- is double a finite value?
Returns non-zero if the input double floating point number is finite, that is, legal for use. On some machines, it is possible for doubles to obtain bit patterns that may not be used meaningfully in subsequent calculations, such as the IEEE NaN and Infinite values.
This routine may be a macro that always evaluates to non-zero on systems where there is no good way to determine whether the value is finite.
Inputs:
| d | Pointer to the double value in question. |
Outputs:
| None |
Returns:
| Zero if d is not finite. Non-zero if d is finite. |
Prototype:
i4 FPdfinite( double *d );
FPexp -- exponential
Find the exponential of x (that is, e**x).
Inputs:
| x | Pointer to the number to find exponential for. |
Outputs:
| result | Pointer to result. |
Returns:
| OK | if operation succeeded. |
| FP_NOT_FINITE_ARGUMENT | when x is not a finite number. |
| FP_OVERFLOW | when the result would overflow. |
| FP_UNDERFLOW | when the result would underflow. |
Exceptions:
| None |
Definition:
STATUS FPexp( double *x, double *result )
FPfadd -- add two doubles
Add two doubles and fill in the result.
Inputs:
| pointer to one double | |
| y | pointer to another |
Outputs:
| result | pointer to the result. |
Returns:
| OK |
| FP_NOT_FINITE_ARGUMENT |
| FP_OVERFLOW |
| FP_UNDERFLOW |
Exceptions:
| None |
Definition:
double FPfadd( double *x, double *y, double *result )
FPfdint -- find integer part of a double
Take the integer part of the passed in double and return it as a double.
Inputs:
| x | Pointer to the double to take the integer part of. |
Outputs:
| None |
Returns:
| The integer part of x (as an double). |
Exceptions:
| None |
Definition:
double FPfdint( double *x )
FPfdiv -- divide two doubles
Divide x by y fill in the result.
Inputs:
| x | pointer to dividend |
| y | pointer to divisor |
Outputs:
| result | pointer to the result. |
Returns:
| OK |
| FP_NOT_FINITE_ARGUMENT |
| FP_OVERFLOW |
| FP_UNDERFLOW |
Exceptions:
| None |
Definition:
double FPfadd( double *x, double *y, double *result )
FPffinite -- is float a finite value?
Returns non-zero if the input floating point number is finite, that is legal for use. On some machines, it is possible for floats to obtain bit patterns that may not be used meaningfully in subsequent calculations, such as the IEEE NaN and Infinite values.
This routine may be a macro that always evaluates to non-zero on systems where there is no good way to determine whether the value is finite.
On non-ANSI C systems, or ANSI systems where this routine is not declared with a prototype and defined in the new style, it is identical to FPdfinite, because of the traditional C widening rules for float arguments.
Inputs:
| f | Pointer to the value in question. |
Outputs:
| None |
Returns:
| Non-zero if the value is finite. |
Prototype:
i4 FPffinite( float *f );
FPfmul -- multiply two doubles
Multiply x by y fill in the result.
Inputs:
| x | pointer to one double |
| y | pointer to another |
Outputs:
| result | pointer to the result. |
Returns:
| OK |
| FP_NOT_FINITE_ARGUMENT |
| FP_OVERFLOW |
| FP_UNDERFLOW |
Exceptions:
| None |
Definition:
double FPfmul( double *x, double *y, double *result )
FPfsub -- subtract two doubles
Subtract y from x and fill in the result
Inputs:
| x | pointer to one double |
| y | pointer to another |
Outputs:
| result | pointer to the result. |
Returns:
| OK |
| FP_NOT_FINITE_ARGUMENT |
| FP_OVERFLOW |
| FP_UNDERFLOW |
Exceptions:
| None |
Definition:
double FPfsub( double *x, double *y, double *result )
FPipow -- integer power
Find x**i.
Inputs:
| x | Pointer to the number to raise to a power. |
| i | Integer power to raise it to. |
Outputs:
| result | Pointer to result. |
Returns:
| OK | if operation succeeded. |
| FP_NOT_FINITE_ARGUMENT | when x is not a finite number. |
| FP_IPOW_DOMAIN_ERR | when x is 0.0 and i <= 0. |
| FP_OVERFLOW | when the result would overflow. |
| FP_UNDERFLOW | when the result would underflow. |
Exceptions:
| None |
Definition:
STATUS FPipow( double *x, i4 i, double *result )
FPln -- natural logarithm
Find the natural logarithm (ln) of x. x must be greater than zero.
Inputs:
| x | Pointer to the number to find log of. |
Outputs:
| result | Pointer to result. |
Returns:
| OK | if operation succeeded. |
| FP_NOT_FINITE_ARGUMENT | when x is not a finite number. |
| FP_LN_DOMAIN_ERR | when x is non-positive. |
Exceptions:
| None |
Definition:
STATUS FPln( double *x, double *result )
FPpkabs -- Take the absolute value of a packed decimal
Takes the absolute value of a packed decimal and returns it as another packed decimal with the same precision and scale.
Inputs:
| pkin | Pointer to the input decimal value. |
| prec | Its precision: 1 <= prec <= 31. |
| scale | Its scale: 0 <= scale <= prec. |
Outputs:
| pkout | The resulting packed decimal value is placed here. It will have the same precision and scale as the input, and its sign will always be positive. |
Returns:
| VOID |
Exceptions:
| None |
Definition:
VOID FPpkabs( PTR pkin, i4 prec, i4 scale, PTR pkout )
FPpkadd -- Add two packed decimals
Adds two packed decimals and returns the result in another packed decimal. The precision and scale of the result are also returned, and are calculated thus:
- pout = min(31, (max(p1 - s1, p2 - s2) + max(s1, s2) + 1))
- sout = max(s1, s2)
Inputs:
| pk1 | Pointer to the 1st input decimal value. |
| p1 | Its precision: 1 <= p1 <= 31. |
| s1 | Its scale: 0 <= s1 <= p1. |
| pk2 | Pointer to the 2nd input decimal value. |
| p2 | Its precision: 1 <= p2 <= 31. |
| s2 | Its scale: 0 <= s2 <= p2. |
Outputs:
| pkout | The resulting packed decimal value is placed here. |
| pout | Its precision will be calculated based on the above formula and placed here. |
| sout | Its scale will be calculated based on the above formula and placed here. |
Returns:
| OK | if the operation succeeded. |
| FP_DECOVF | when the result has too many non-fractional digits; that is, more than (pout - sout) of them. |
Exceptions:
| None |
Definition:
STATUS
FPpkadd( PTR pk1, i4 p1, i4 s1,
PTR pk2, i4 p2, i4 s2,
PTR pkout, i4 *pout, i4 *sout )
FPpkceil -- Take the ceiling of a packed decimal
Takes the ceiling of a packed decimal and returns it as another packed decimal with the same precision and scale. The ceiling is the smallest integer not less than the input.
Inputs:
| pkin | Pointer to the input decimal value. |
| prec | Its precision: 1 <= prec <= 31. |
| scale | Its scale: 0 <= scale <= prec. |
Outputs:
| pkout | The resulting packed decimal value is placed here. It will have the same precision and scale as the input. |
Returns:
| OK | if the operation succeeded. |
| FP_DECOVF | when the result has too many non-fractional digits; that is, more than (prec - scale) of them. |
Exceptions:
| None |
Definition:
STATUS FPpkceil( PTR pkin, i4 prec, i4 scale, PTR pkout )
FPpkcmp -- Compare two packed decimals
Compares two packed decimals and returns 1 if the first is greater the second, -1 if the first is less than the second, and 0 if they are equal.
Inputs:
| pk1 | Pointer to the 1st input decimal value. |
| p1 | Its precision: 1 <= p1 <= 31. |
| s1 | Its scale: 0 <= s1 <= p1. |
| pk2 | Pointer to the 2nd input decimal value. |
| p2 | Its precision: 1 <= p2 <= 31. |
| s2 | Its scale: 0 <= s2 <= p2. |
Outputs:
| NONE |
Returns:
| 1 | If the first is greater than second. |
| 0 | If the first is equal to second. |
| -1 | If the first is less than second. |
Exceptions:
| None |
Definition:
i4 FPpkcmp( PTR pk1, i4 p1, i4 s1, PTR pk2, i4 p2, i4 s2 )
FPpkdiv -- Divide two packed decimals
Divides two packed decimals and returns the result in another packed decimal. The precision and scale of the result are also returned, and are calculated thus:
- pout = 31
- sout = max(0, (31 - p1 + s1 - s2))
Inputs:
| pk1 | Pointer to the 1st input decimal value; the numerator. |
| p1 | Its precision: 1 <= p1 <= 31. |
| s1 | Its scale: 0 <= s1 <= p1. |
| pk2 | Pointer to the 2nd input decimal value; the denomii4or. |
| p2 | Its precision: 1 <= p2 <= 31. |
| s2 | Its scale: 0 <= s2 <= p2. |
Outputs:
| pkout | The resulting packed decimal value is placed here. |
| pout | Its precision will be calculated based on the above formula and placed here. |
| sout | Its scale will be calculated based on the above formula and placed here. |
Returns:
| OK | if the operation succeeded. |
| FP_DECOVF | when the result has too many non-fractional digits; that is, more than (pout - sout) of them. |
| FP_DECDIV | Attempt to divide by zero. The denomii4or (2nd input decimal value) is equal to zero. |
Exceptions:
| None |
Definition:
STATUS
FPpkdiv( PTR pk1, i4 p1, i4 s1,
PTR pk2, i4 p2, i4 s2,
PTR pkout, i4 *pout, i4 *sout )
FPpkint -- Take the integer part of a packed decimal
Takes the integer part of a packed decimal and returns it as another packed decimal with the same precision and scale.
Inputs:
| pkin | Pointer to the input decimal value. |
| prec | Its precision: 1 <= prec <= 31. |
| scale | Its scale: 0 <= scale <= prec. |
Outputs:
| pkout | The resulting packed decimal value is placed here. It will have the same precision and scale as the input. |
Returns:
| VOID |
Exceptions:
| None |
Definition:
VOID FPpkint( PTR pkin, i4 prec, i4 scale, PTR pkout )
FPpkmul -- Multiply two packed decimals
Multiplies two packed decimals and returns the result in another packed decimal. The precision and scale of the result are also returned, and are calculated thus:
- pout = min(31, (p1 + p2))
- sout = min(31, (s1 + s2))
Inputs:
| pk1 | Pointer to the 1st input decimal value. |
| p1 | Its precision: 1 <= p1 <= 31. |
| s1 | Its scale: 0 <= s1 <= p1. |
| pk2 | Pointer to the 2nd input decimal value. |
| p2 | Its precision: 1 <= p2 <= 31. |
| s2 | Its scale: 0 <= s2 <= p2. |
Outputs:
| pkout | The resulting packed decimal value is placed here. |
| pout | Its precision will be calculated based on the above formula and placed here. |
| sout | Its scale will be calculated based on the above formula and placed here. |
Returns:
| OK | if the operation succeeded. |
| FP_DECOVF | when the result has too many non-fractional digits; that is, more than (pout - sout) of them. |
Exceptions:
| None |
Definition:
STATUS
FPpkmul( PTR pk1, i4 p1, i4 s1,
PTR pk2, i4 p2, i4 s2,
PTR pkout, i4 *pout, i4 *sout )
FPpkneg -- Negate (complement) a packed decimal
Complements the sign of a packed decimal and returns it as another packed decimal with the same precision and scale. If the input was positive, the output will be negative. If the input was negative, the output will be positive.
Inputs:
| pkin | Pointer to the input decimal value. |
| prec | Its precision: 1 <= prec <= 31. |
| scale | Its scale: 0 <= scale <= prec. |
Outputs:
| pkout | The resulting packed decimal value is placed here. It will have the same precision and scale as the input, but a different sign. |
Returns:
| VOID |
Exceptions:
| None |
Definition:
VOID FPpkneg( PTR pkin, i4 prec, i4 scale, PTR pkout )
FPpksub -- Subtract two packed decimals
Subtracts two packed decimals and returns the result in another packed decimal. The precision and scale of the result are also returned, and are calculated thus:
- pout = min(31, (max(p1 - s1, p2 - s2) + max(s1, s2) + 1))
- sout = max(s1, s2)
Inputs:
| pk1 | Pointer to the 1st input decimal value. |
| p1 | Its precision: 1 <= p1 <= 31. |
| s1 | Its scale: 0 <= s1 <= p1. |
| pk2 | Pointer to the 2nd input decimal value. |
| p2 | Its precision: 1 <= p2 <= 31. |
| s2 | Its scale: 0 <= s2 <= p2. |
Outputs:
| pkout | The resulting packed decimal value is placed here. |
| pout | Its precision will be calculated based on the above formula and placed here. |
| sout | Its scale will be calculated based on the above formula and placed here. |
Returns:
| OK | if the operation succeeded. |
| FP_DECOVF | when the result has too many non-fractional digits; that is, more than (pout - sout) of them. |
Exceptions:
| None |
Definition:
STATUS
FPpksub( PTR pk1, i4 p1, i4 s1,
PTR pk2, i4 p2, i4 s2,
PTR pkout, i4 *pout, i4 *sout )
FPpow -- power
Find x**y.
Inputs:
| x | Pointer to the number to raise to a power. |
| y | Power to raise it to. |
Outputs:
| result | Pointer to result. |
Returns:
| OK | if operation succeeded. |
| FP_NOT_FINITE_ARGUMENT | when x is not a finite number. |
| FP_POW_DOMAIN_ERR | when x is 0.0 and y <= 0, or x < 0.0 and y is not an integer. |
| FP_OVERFLOW | when the result would overflow. |
| FP_UNDERFLOW | when the result would underflow. |
Exceptions:
| None |
Definition:
STATUS FPpow( double *x, double *y, double *result )
FPrand -- random number
Return the next random number. That is, each time this routine is called it will return the next number in a sequence of pseudo-random numbers. FPsrand will reset the random number generator used by FPrand; it is a good idea to seed the random number generator by calling FPsrand before FPrand is called for the first time.
Inputs:
| None |
Outputs:
| None |
Returns:
| A random number r where 0.0 \(<= r < 1.0. That is, r includes 0.0, but not 1.0. |
Exceptions:
| None |
Definition:
double FPrand( void )
FPsin -- sine
Find the sine of x, where x is in radians.
Inputs:
| x | Pointer to the number of radians to take sine of. |
Outputs:
| result | Pointer to result. |
Returns:
| OK | if operation succeeded. |
| FP_NOT_FINITE_ARGUMENT | when x is not a finite number. |
Exceptions:
| None |
Definition:
STATUS FPsin( double *x, double *result )
FPsqrt -- square root
Find the square root of x. Only works if x is non-negative.
Inputs:
| x | Pointer to the number to find square root of. |
Outputs:
| result | Pointer to result. |
Returns:
| OK | if operation succeeded. |
| FP_NOT_FINITE_ARGUMENT | when x is not a finite number. |
| FP_SQRT_DOMAIN_ERR | when x is < 0.0. |
Exceptions:
| None |
Definition:
STATUS FPsqrt( double *x, double *result )
FPsrand -- set/seed random number generator
Initialize the random number generator used by FPrand() to a particular starting point.
Inputs:
| seed | Any number; time values are good seeds. |
Outputs:
| None |
Returns:
| None |
Side Effects:
| Will reset the random number generator used by FPrand. |
Exceptions:
| None |
Definition:
VOID FPsrand( i4 seed )
|
Ingres Compatability Library |
