113 lines
4.1 KiB
C
113 lines
4.1 KiB
C
/*
|
|
* (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
*/
|
|
/** @file
|
|
* High precision floating point arithmetic module.
|
|
*
|
|
* Before each operation, the `#flt_status` variable is reset to 0.
|
|
*
|
|
*
|
|
*/
|
|
#ifndef __FLT_INCLUDED__
|
|
#define __FLT_INCLUDED__
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifndef arith
|
|
#define arith long
|
|
#endif
|
|
|
|
struct flt_mantissa {
|
|
uint32_t flt_h_32; /**< high order 32 bits of mantissa */
|
|
uint32_t flt_l_32; /**< low order 32 bits of mantissa */
|
|
};
|
|
|
|
typedef struct flt_arith {
|
|
short flt_sign; /**< 0 for positive, 1 for negative */
|
|
short flt_exp; /**< between -16384 and 16384 */
|
|
struct flt_mantissa flt_mantissa; /**< mantissa normalized, in [1,2). */
|
|
} flt_arith;
|
|
|
|
/** Status of last floating point operation. */
|
|
extern int flt_status;
|
|
/** An overflow occurred. */
|
|
#define FLT_OVFL 001
|
|
/** An underflow occurred. The result is 0. */
|
|
#define FLT_UNFL 002
|
|
/** Divide by 0. */
|
|
#define FLT_DIV0 004
|
|
/** String cannot be represented into a real number. */
|
|
#define FLT_NOFLT 010
|
|
/** Buffer is too small. */
|
|
#define FLT_BTSM 020
|
|
|
|
#define FLT_STRLEN 32 /**< max length of result of flt_flt2str() */
|
|
|
|
/** Adds the numbers indicated by `e1` and `e2` and stores the result
|
|
* in `res`. */
|
|
void flt_add(flt_arith *e1, flt_arith *e2, flt_arith *res);
|
|
/** Subtracts the number indicated by `e2` from the one indicated by
|
|
* `e1` and stores the result in `res`. */
|
|
void flt_sub(flt_arith *e1, flt_arith *e2, flt_arith *res);
|
|
/** Multiplies the numbers indicated by `e1` and `e2` and stores the
|
|
* result in `res`. */
|
|
void flt_mul(flt_arith *e1, flt_arith *e2, flt_arith *res);
|
|
/** Divides the number indicated by `e1` by the one indicated by `e2`
|
|
* and stores the result in `res`.
|
|
*/
|
|
void flt_div(flt_arith *e1, flt_arith *e2, flt_arith *res);
|
|
/** Splits the number indicated by `e` in an integer and a fraction
|
|
* part, and stores the integer part through `ipart` and the fraction part
|
|
* through `fpart`. Also, the absolute value of the number indicated by
|
|
* `ipart` is less than or equal to the absolute value of the number
|
|
* indicated by `e`. The absolute value of the number indicated by
|
|
* `fpart` is less than 1.
|
|
*/
|
|
void flt_modf(flt_arith *e, flt_arith *ipart, flt_arith *fpart);
|
|
/** Compares the numbers indicated by `e1` and `e2` and returns -1 if
|
|
* `e1` < `e2`, 0 if `e1` = `e2`, and 1 if `e1` > `e2`.
|
|
*/
|
|
int flt_cmp(flt_arith *e1, flt_arith *e2);
|
|
|
|
/** Converts the string indicated by `s` to a floating point number,
|
|
* and stores this number through `e`. The string should contain a
|
|
* floating point constant, which consists of an integer part, a decimal
|
|
* point, a fraction part, an e or an E, and an optionally signed integer
|
|
* exponent. The integer and fraction parts both consist of a sequence of
|
|
* digits. They may not both be missing. The decimal point, the e and the
|
|
* exponent may be missing.
|
|
*/
|
|
void flt_str2flt(char *s, flt_arith *e);
|
|
/** Converts the number indicated by `e` into a string, in a scientific
|
|
* notation acceptable for EM. The result is stored in `buf`. At most
|
|
* `bufsize` characters are stored. The maximum length needed is
|
|
* available in the constant `#FLT_STRLEN`.
|
|
*/
|
|
void flt_flt2str(flt_arith *e, char *buf, int bufsize);
|
|
/** Converts the number `n` to the floating point format used
|
|
* in this package and returns the result in `e`. If the `uns`
|
|
* flag is set, the number n is regarded as an unsigned.
|
|
*/
|
|
void flt_arith2flt(arith n, flt_arith *e, int uns);
|
|
/** Truncates the number indicated by `e` to the largest integer
|
|
* value smaller than or equal to the number indicated by `e`. It
|
|
* returns this value. If the uns flag is set, the result is to be
|
|
* regarded as unsigned.
|
|
*/
|
|
arith flt_flt2arith(register flt_arith *e, int uns);
|
|
/** Negates the number indicated by `e` and stores the result
|
|
* in `e`. */
|
|
void flt_umin(flt_arith *e);
|
|
/** Shifts the mantissa m |n| bits left or right, depending on the sign
|
|
* of n. If n is negative, it is a left-shift; If n is positive,
|
|
* it is a right shift.
|
|
*/
|
|
void flt_b64_sft(
|
|
register struct flt_mantissa *e,
|
|
register int n);
|
|
|
|
|
|
|
|
|
|
#endif /* __FLT_INCLUDED__ */
|