FLT_ARITH(3ACK)

NAME
flt_arith - high precision floating point arithmetic

SYNOPSIS
#include <flt_arith.h>

struct flt_mantissa {
	long	flt_h_32;	/* high order 32 bits of mantissa */
	long	flt_l_32;	/* low order 32 bits of mantissa */
};
typedef struct {
	short	flt_sign;	/* 0 for positive, 1 for negative */
	short	flt_exp;	/* between -16384 and 16384 */
	struct flt_mantissa	flt_mantissa;	/* normalized, in [1,2). */
} flt_arith;
extern int	flt_status;
#define FLT_OVFL	001
#define FLT_UNFL	002
#define FLT_DIV0	004
#define FLT_NOFLT	010
#define FLT_BTSM	020
#define FLT_STRLEN	32

flt_add(e1, e2, e3)
flt_arith *e1, *e2, *e3;

flt_mul(e1, e2, e3)
flt_arith *e1, *e2, *e3;

flt_sub(e1, e2, e3)
flt_arith *e1, *e2, *e3;

flt_div(e1, e2, e3)
flt_arith *e1, *e2, *e3;

flt_umin(e)
flt_arith *e;

flt_modf(e1, intpart, fractpart)
flt_arith *e1, *intpart, *fractpart;

int flt_cmp(e1, e2)
flt_arith *e1, *e2;

flt_str2flt(s, e)
char *s;
flt_arith *e;

flt_flt2str(e, buf, bufsize)
flt_arith *e;
char *buf;
int bufsize;

int flt_status;

#include <em_arith.h>
flt_arith2flt(n, e)
arith n;
flt_arith *e;

arith flt_flt2arith(e)
flt_arith *e;

flt_b64_sft(m, n)
struct flt_mantissa *m;
int n;

flt_b64_rsft(m)
struct flt_mantissa *m;

flt_b64_lsft(m)
struct flt_mantissa *m;

DESCRIPTION
This set of routines emulates floating point arithmetic, in a high precision. It is intended primarily for compilers that need to evaluate floating point expressions at compile-time. It could be argued that this should be done in the floating point arithmetic of the target machine, but EM does not define its floating point arithmetic.

flt_add adds the numbers indicated by e1 and e2 and stores the result indirectly through e3.

flt_mul multiplies the numbers indicated by e1 and e2 and stores the result indirectly through e3.

flt_sub subtracts the number indicated by e2 from the one indicated by e1 and stores the result indirectly through e3.

flt_div divides the number indicated by e1 by the one indicated by e2 and stores the result indirectly through e3.

flt_umin negates the number indicated by e and stores the result indirectly through e.

flt_modf splits the number indicated by e in an integer and a fraction part, and stores the integer part through intpart and the fraction part through fractpart. So, adding the numbers indicated by intpart and fractpart results (in the absence of rounding error) in the number indicated by e. Also, the absolute value of the number indicated by intpart is less than or equal to the absolute value of the number indicated by e. The absolute value of the number indicated by fractpart is less than 1.

flt_cmp compares the numbers indicated by e1 and e2 and returns -1 if e1 < e2, 0 if e1 = e2, and 1 if e1 > e2.

flt_str2flt 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.

flt_flt2str 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.

flt_arith2flt converts the number n to the floating point format used in this package and returns the result in e.

flt_flt2arith 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.

Before each operation, the flt_status variable is reset to 0. After an operation, it can be checked for one of the following values:

FLT_OVFL
    an overflow occurred. The result is a large value with the correct sign. This can occur with the routines flt_add, flt_sub, flt_div, flt_mul, flt_flt2arith, and flt_str2flt.

FLT_UNFL
    an underflow occurred. The result is 0. This can occur with the routines flt_div, flt_mul, flt_sub, flt_add, and flt_str2flt.

FLT_DIV0
    divide by 0. The result is a large value with the sign of the dividend. This can only occur with the routine flt_div.

FLT_NOFLT
    indicates that the string did not represent a floating point number. The result is 0. This can only occur with the routine flt_str2flt.

FLT_BTSM
    indicates that the buffer is too small. The contents of the buffer is undefined. This can only occur with the routine flt_flt2str.

The routine flt_b64_sft 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.

The routine flt_b64_rsft shifts the mantissa m 1 bit right.

The routine flt_b64_lsft shifts the mantissa m 1 bit left.

FILES
~em/modules/h/flt_arith.h
~em/modules/h/em_arith.h
~em/modules/lib/libflt.a