ANSI C conversion of code, rename some parameters to better names and adapt man page accordingly.
This commit is contained in:
parent
dc269e57d8
commit
add131b6f9
|
@ -7,10 +7,9 @@
|
||||||
|
|
||||||
#include "flt_misc.h"
|
#include "flt_misc.h"
|
||||||
|
|
||||||
void
|
void flt_b64_sft(
|
||||||
flt_b64_sft(e,n)
|
register struct flt_mantissa *e,
|
||||||
register struct flt_mantissa *e;
|
register int n)
|
||||||
register int n;
|
|
||||||
{
|
{
|
||||||
if (n > 63 || n < -63) {
|
if (n > 63 || n < -63) {
|
||||||
e->flt_l_32 = 0;
|
e->flt_l_32 = 0;
|
||||||
|
|
|
@ -7,23 +7,18 @@
|
||||||
|
|
||||||
#include "flt_misc.h"
|
#include "flt_misc.h"
|
||||||
|
|
||||||
void
|
void flt_add(flt_arith *e1, flt_arith *e2,flt_arith *res)
|
||||||
flt_add(e1,e2,e3)
|
|
||||||
register flt_arith *e1,*e2,*e3;
|
|
||||||
{
|
{
|
||||||
/* Add two extended numbers e1 and e2, and put the result
|
|
||||||
in e3
|
|
||||||
*/
|
|
||||||
flt_arith ce1, ce2;
|
flt_arith ce1, ce2;
|
||||||
int diff;
|
int diff;
|
||||||
|
|
||||||
flt_status = 0;
|
flt_status = 0;
|
||||||
if ((e2->m1 | e2->m2) == 0L) {
|
if ((e2->m1 | e2->m2) == 0L) {
|
||||||
*e3 = *e1;
|
*res = *e1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((e1->m1 | e1->m2) == 0L) {
|
if ((e1->m1 | e1->m2) == 0L) {
|
||||||
*e3 = *e2;
|
*res = *e2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ce2 = *e2;
|
ce2 = *e2;
|
||||||
|
@ -52,33 +47,31 @@ flt_add(e1,e2,e3)
|
||||||
}
|
}
|
||||||
e1->m1 -= e2->m1;
|
e1->m1 -= e2->m1;
|
||||||
e1->m2 -= e2->m2;
|
e1->m2 -= e2->m2;
|
||||||
*e3 = *e1;
|
*res = *e1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (e1->m2 > e2->m2)
|
if (e1->m2 > e2->m2)
|
||||||
e2->m1 -= 1; /* carry in */
|
e2->m1 -= 1; /* carry in */
|
||||||
e2->m1 -= e1->m1;
|
e2->m1 -= e1->m1;
|
||||||
e2->m2 -= e1->m2;
|
e2->m2 -= e1->m2;
|
||||||
*e3 = *e2;
|
*res = *e2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*e3 = *e2;
|
*res = *e2;
|
||||||
if (flt_b64_add(&e3->flt_mantissa,&e1->flt_mantissa)) {/* addition carry */
|
if (flt_b64_add(&res->flt_mantissa,&e1->flt_mantissa)) {/* addition carry */
|
||||||
flt_b64_sft(&e3->flt_mantissa, 1);
|
flt_b64_sft(&res->flt_mantissa, 1);
|
||||||
e3->m1 |= 0x80000000L; /* set max bit */
|
res->m1 |= 0x80000000L; /* set max bit */
|
||||||
e3->flt_exp++; /* increase the exponent */
|
res->flt_exp++; /* increase the exponent */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flt_nrm(e3);
|
flt_nrm(res);
|
||||||
flt_chk(e3);
|
flt_chk(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void flt_sub(flt_arith *e1, flt_arith *e2, flt_arith *res)
|
||||||
flt_sub(e1,e2,e3)
|
|
||||||
flt_arith *e1,*e2,*e3;
|
|
||||||
{
|
{
|
||||||
e2->flt_sign = ! e2->flt_sign;
|
e2->flt_sign = ! e2->flt_sign;
|
||||||
flt_add(e1,e2,e3);
|
flt_add(e1,e2,res);
|
||||||
e2->flt_sign = ! e2->flt_sign;
|
e2->flt_sign = ! e2->flt_sign;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,7 @@
|
||||||
#include "flt_misc.h"
|
#include "flt_misc.h"
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
|
|
||||||
void
|
void flt_arith2flt(arith n, flt_arith *e, int uns)
|
||||||
flt_arith2flt(n, e, uns)
|
|
||||||
register arith n;
|
|
||||||
register flt_arith *e;
|
|
||||||
{
|
{
|
||||||
/* Convert the arith "n" to a flt_arith "e".
|
/* Convert the arith "n" to a flt_arith "e".
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -28,51 +28,32 @@ extern int flt_status;
|
||||||
|
|
||||||
#define FLT_STRLEN 32
|
#define FLT_STRLEN 32
|
||||||
.PP
|
.PP
|
||||||
.B void flt_add(e1, e2, e3)
|
.B void flt_add(flt_arith *e1, flt_arith *e2,flt_arith *res)
|
||||||
.B flt_arith *e1, *e2, *e3;
|
|
||||||
.PP
|
.PP
|
||||||
.B void flt_mul(e1, e2, e3)
|
.B void flt_mul(flt_arith *e1, flt_arith *e2, flt_arith *res)
|
||||||
.B flt_arith *e1, *e2, *e3;
|
|
||||||
.PP
|
.PP
|
||||||
.B void flt_sub(e1, e2, e3)
|
.B void flt_sub(flt_arith *e1, flt_arith *e2, flt_arith *res)
|
||||||
.B flt_arith *e1, *e2, *e3;
|
|
||||||
.PP
|
.PP
|
||||||
.B void flt_div(e1, e2, e3)
|
.B void flt_div(flt_arith *e1, flt_arith *e2, flt_arith *res)
|
||||||
.B flt_arith *e1, *e2, *e3;
|
|
||||||
.PP
|
.PP
|
||||||
.B void flt_umin(e)
|
.B void flt_umin(flt_arith *e)
|
||||||
.B flt_arith *e;
|
|
||||||
.PP
|
.PP
|
||||||
.B void flt_modf(e1, intpart, fractpart)
|
.B void flt_modf(flt_arith *e, flt_arith *ipart, flt_arith *fpart)
|
||||||
.B flt_arith *e1, *intpart, *fractpart;
|
|
||||||
.PP
|
.PP
|
||||||
.B int flt_cmp(e1, e2)
|
.B int flt_cmp(flt_arith *e1, flt_arith *e2)
|
||||||
.B flt_arith *e1, *e2;
|
|
||||||
.PP
|
.PP
|
||||||
.B void flt_str2flt(s, e)
|
.B void flt_str2flt(char *s, flt_arith *e)
|
||||||
.B char *s;
|
|
||||||
.B flt_arith *e;
|
|
||||||
.PP
|
.PP
|
||||||
.B void flt_flt2str(e, buf, bufsize)
|
.B void flt_flt2str(flt_arith *e, char *buf, int bufsize)
|
||||||
.B flt_arith *e;
|
|
||||||
.B char *buf;
|
|
||||||
.B int bufsize;
|
|
||||||
.PP
|
.PP
|
||||||
.B int flt_status;
|
.B int flt_status;
|
||||||
.PP
|
.PP
|
||||||
.B #include <em_arith.h>
|
.B #include <em_arith.h>
|
||||||
.B void flt_arith2flt(n, e, uns)
|
.B void flt_arith2flt(arith n, flt_arith *e, int uns)
|
||||||
.B arith n;
|
|
||||||
.B flt_arith *e;
|
|
||||||
.B int uns;
|
|
||||||
.PP
|
.PP
|
||||||
.B arith flt_flt2arith(e, uns)
|
.B arith flt_flt2arith(register flt_arith *e, int uns)
|
||||||
.B flt_arith *e;
|
|
||||||
.B int uns;
|
|
||||||
.PP
|
.PP
|
||||||
.B void flt_b64_sft(m, n)
|
.B void flt_b64_sft(register struct flt_mantissa *e, register int n)
|
||||||
.B struct flt_mantissa *m;
|
|
||||||
.B int n;
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This set of routines emulates floating point arithmetic, in a high
|
This set of routines emulates floating point arithmetic, in a high
|
||||||
precision. It is intended primarily for compilers that need to evaluate
|
precision. It is intended primarily for compilers that need to evaluate
|
||||||
|
@ -86,7 +67,7 @@ adds the numbers indicated by
|
||||||
and
|
and
|
||||||
.I e2
|
.I e2
|
||||||
and stores the result indirectly through
|
and stores the result indirectly through
|
||||||
.IR e3 .
|
.IR res.
|
||||||
.PP
|
.PP
|
||||||
.B flt_mul
|
.B flt_mul
|
||||||
multiplies the numbers indicated by
|
multiplies the numbers indicated by
|
||||||
|
@ -94,7 +75,7 @@ multiplies the numbers indicated by
|
||||||
and
|
and
|
||||||
.I e2
|
.I e2
|
||||||
and stores the result indirectly through
|
and stores the result indirectly through
|
||||||
.IR e3 .
|
.IR res.
|
||||||
.PP
|
.PP
|
||||||
.B flt_sub
|
.B flt_sub
|
||||||
subtracts the number indicated by
|
subtracts the number indicated by
|
||||||
|
@ -102,7 +83,7 @@ subtracts the number indicated by
|
||||||
from the one indicated by
|
from the one indicated by
|
||||||
.I e1
|
.I e1
|
||||||
and stores the result indirectly through
|
and stores the result indirectly through
|
||||||
.IR e3 .
|
.IR res .
|
||||||
.PP
|
.PP
|
||||||
.B flt_div
|
.B flt_div
|
||||||
divides the number indicated by
|
divides the number indicated by
|
||||||
|
@ -110,7 +91,7 @@ divides the number indicated by
|
||||||
by the one indicated by
|
by the one indicated by
|
||||||
.I e2
|
.I e2
|
||||||
and stores the result indirectly through
|
and stores the result indirectly through
|
||||||
.IR e3 .
|
.IR res.
|
||||||
.PP
|
.PP
|
||||||
.B flt_umin
|
.B flt_umin
|
||||||
negates the number indicated by
|
negates the number indicated by
|
||||||
|
@ -124,20 +105,20 @@ splits the number indicated by
|
||||||
in an integer and a fraction part, and stores the integer part through
|
in an integer and a fraction part, and stores the integer part through
|
||||||
.I intpart
|
.I intpart
|
||||||
and the fraction part through
|
and the fraction part through
|
||||||
.IR fractpart .
|
.IR fpart .
|
||||||
So, adding the numbers indicated by
|
So, adding the numbers indicated by
|
||||||
.I intpart
|
.I ipart
|
||||||
and
|
and
|
||||||
.I fractpart
|
.I fpart
|
||||||
results (in the absence of rounding error) in the number
|
results (in the absence of rounding error) in the number
|
||||||
indicated by
|
indicated by
|
||||||
.IR e .
|
.IR e .
|
||||||
Also, the absolute value of the number indicated by
|
Also, the absolute value of the number indicated by
|
||||||
.I intpart
|
.I ipart
|
||||||
is less than or equal to the absolute value of the number indicated by
|
is less than or equal to the absolute value of the number indicated by
|
||||||
.IR e .
|
.IR e .
|
||||||
The absolute value of the number indicated by
|
The absolute value of the number indicated by
|
||||||
.I fractpart
|
.I fpart
|
||||||
is less than 1.
|
is less than 1.
|
||||||
.PP
|
.PP
|
||||||
.B flt_cmp
|
.B flt_cmp
|
||||||
|
|
|
@ -2,8 +2,13 @@
|
||||||
* (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
* (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/** @file
|
||||||
|
* High precision floating point arithmetic module.
|
||||||
|
*
|
||||||
|
* Before each operation, the `#flt_status` variable is reset to 0.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
#ifndef __FLT_INCLUDED__
|
#ifndef __FLT_INCLUDED__
|
||||||
#define __FLT_INCLUDED__
|
#define __FLT_INCLUDED__
|
||||||
|
|
||||||
|
@ -14,36 +19,95 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct flt_mantissa {
|
struct flt_mantissa {
|
||||||
uint32_t flt_h_32; /* high order 32 bits of mantissa */
|
uint32_t flt_h_32; /**< high order 32 bits of mantissa */
|
||||||
uint32_t flt_l_32; /* low order 32 bits of mantissa */
|
uint32_t flt_l_32; /**< low order 32 bits of mantissa */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct flt_arith {
|
typedef struct flt_arith {
|
||||||
short flt_sign; /* 0 for positive, 1 for negative */
|
short flt_sign; /**< 0 for positive, 1 for negative */
|
||||||
short flt_exp; /* between -16384 and 16384 */
|
short flt_exp; /**< between -16384 and 16384 */
|
||||||
struct flt_mantissa flt_mantissa; /* normalized, in [1,2). */
|
struct flt_mantissa flt_mantissa; /**< mantissa normalized, in [1,2). */
|
||||||
} flt_arith;
|
} flt_arith;
|
||||||
|
|
||||||
|
/** Status of last floating point operation. */
|
||||||
extern int flt_status;
|
extern int flt_status;
|
||||||
|
/** An overflow occurred. */
|
||||||
#define FLT_OVFL 001
|
#define FLT_OVFL 001
|
||||||
|
/** An underflow occurred. The result is 0. */
|
||||||
#define FLT_UNFL 002
|
#define FLT_UNFL 002
|
||||||
|
/** Divide by 0. */
|
||||||
#define FLT_DIV0 004
|
#define FLT_DIV0 004
|
||||||
|
/** String cannot be represented into a real number. */
|
||||||
#define FLT_NOFLT 010
|
#define FLT_NOFLT 010
|
||||||
|
/** Buffer is too small. */
|
||||||
#define FLT_BTSM 020
|
#define FLT_BTSM 020
|
||||||
|
|
||||||
#define FLT_STRLEN 32 /* max length of result of flt_flt2str() */
|
#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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void flt_add(flt_arith *, flt_arith *, flt_arith *);
|
|
||||||
void flt_sub(flt_arith *, flt_arith *, flt_arith *);
|
|
||||||
void flt_mul(flt_arith *, flt_arith *, flt_arith *);
|
|
||||||
void flt_div(flt_arith *, flt_arith *, flt_arith *);
|
|
||||||
void flt_modf(flt_arith *, flt_arith *, flt_arith *);
|
|
||||||
int flt_cmp(flt_arith *, flt_arith *);
|
|
||||||
void flt_str2flt(char *, flt_arith *);
|
|
||||||
void flt_flt2str(flt_arith *, char *, int);
|
|
||||||
void flt_arith2flt(arith, flt_arith *, int);
|
|
||||||
arith flt_flt2arith(flt_arith *, int);
|
|
||||||
void flt_b64_sft(struct flt_mantissa *, int);
|
|
||||||
void flt_umin(flt_arith *);
|
|
||||||
|
|
||||||
#endif /* __FLT_INCLUDED__ */
|
#endif /* __FLT_INCLUDED__ */
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
|
|
||||||
#include "flt_misc.h"
|
#include "flt_misc.h"
|
||||||
|
|
||||||
int
|
int flt_cmp(flt_arith *e1, flt_arith *e2)
|
||||||
flt_cmp(e1, e2)
|
|
||||||
register flt_arith *e1, *e2;
|
|
||||||
{
|
{
|
||||||
flt_arith x;
|
flt_arith x;
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "flt_misc.h"
|
#include "flt_misc.h"
|
||||||
|
|
||||||
void
|
void flt_div(flt_arith *e1,flt_arith *e2,flt_arith *res)
|
||||||
flt_div(e1,e2,e3)
|
|
||||||
register flt_arith *e1,*e2,*e3;
|
|
||||||
{
|
{
|
||||||
uint32_t result[2];
|
uint32_t result[2];
|
||||||
register uint32_t *rp;
|
register uint32_t *rp;
|
||||||
|
@ -21,21 +19,21 @@ flt_div(e1,e2,e3)
|
||||||
flt_arith cpe1 = *e1;
|
flt_arith cpe1 = *e1;
|
||||||
|
|
||||||
flt_status = 0;
|
flt_status = 0;
|
||||||
e3->flt_sign = e1->flt_sign ^ e2->flt_sign;
|
res->flt_sign = e1->flt_sign ^ e2->flt_sign;
|
||||||
if ((e2->m1 | e2->m2) == 0) {
|
if ((e2->m1 | e2->m2) == 0) {
|
||||||
flt_status = FLT_DIV0;
|
flt_status = FLT_DIV0;
|
||||||
e3->flt_exp = EXT_MAX;
|
res->flt_exp = EXT_MAX;
|
||||||
e3->m1 = 0x80000000;
|
res->m1 = 0x80000000;
|
||||||
e3->m2 = 0L;
|
res->m2 = 0L;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((e1->m1 | e1->m2) == 0) { /* 0 / anything == 0 */
|
if ((e1->m1 | e1->m2) == 0) { /* 0 / anything == 0 */
|
||||||
e3->flt_exp = 0; /* make sure */
|
res->flt_exp = 0; /* make sure */
|
||||||
e3->m1 = e3->m2 = 0L;
|
res->m1 = res->m2 = 0L;
|
||||||
e3->flt_sign = 0;
|
res->flt_sign = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e3->flt_exp = e1->flt_exp - e2->flt_exp;
|
res->flt_exp = e1->flt_exp - e2->flt_exp;
|
||||||
|
|
||||||
u[4] = (e1->m2 & 1) << 15;
|
u[4] = (e1->m2 & 1) << 15;
|
||||||
flt_b64_sft(&(cpe1.flt_mantissa),1);
|
flt_b64_sft(&(cpe1.flt_mantissa),1);
|
||||||
|
@ -112,9 +110,9 @@ flt_div(e1,e2,e3)
|
||||||
*rp |= (j & 1) ? q_est : (q_est<<16);
|
*rp |= (j & 1) ? q_est : (q_est<<16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e3->m1 = result[0];
|
res->m1 = result[0];
|
||||||
e3->m2 = result[1];
|
res->m2 = result[1];
|
||||||
|
|
||||||
flt_nrm(e3);
|
flt_nrm(res);
|
||||||
flt_chk(e3);
|
flt_chk(res);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
#include "flt_misc.h"
|
#include "flt_misc.h"
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
|
|
||||||
arith
|
arith flt_flt2arith(register flt_arith *e, int uns)
|
||||||
flt_flt2arith(e, uns)
|
|
||||||
register flt_arith *e;
|
|
||||||
{
|
{
|
||||||
/* Convert the flt_arith "n" to an arith.
|
/* Convert the flt_arith "n" to an arith.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
|
|
||||||
#include "flt_misc.h"
|
#include "flt_misc.h"
|
||||||
|
|
||||||
void
|
void flt_modf(flt_arith *e, flt_arith *ipart, flt_arith *fpart)
|
||||||
flt_modf(e, ipart, fpart)
|
|
||||||
register flt_arith *e, *ipart, *fpart;
|
|
||||||
{
|
{
|
||||||
if (e->flt_exp < 0) {
|
if (e->flt_exp < 0) {
|
||||||
*fpart = *e;
|
*fpart = *e;
|
||||||
|
|
|
@ -8,13 +8,8 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "flt_misc.h"
|
#include "flt_misc.h"
|
||||||
|
|
||||||
void
|
void flt_mul(flt_arith *e1, flt_arith *e2, flt_arith *res)
|
||||||
flt_mul(e1,e2,e3)
|
|
||||||
register flt_arith *e1,*e2,*e3;
|
|
||||||
{
|
{
|
||||||
/* Multiply the extended numbers e1 and e2, and put the
|
|
||||||
result in e3.
|
|
||||||
*/
|
|
||||||
register int i,j; /* loop control */
|
register int i,j; /* loop control */
|
||||||
unsigned short mp[4];
|
unsigned short mp[4];
|
||||||
unsigned short mc[4];
|
unsigned short mc[4];
|
||||||
|
@ -25,10 +20,10 @@ flt_mul(e1,e2,e3)
|
||||||
flt_status = 0;
|
flt_status = 0;
|
||||||
|
|
||||||
/* first save the sign (XOR) */
|
/* first save the sign (XOR) */
|
||||||
e3->flt_sign = e1->flt_sign ^ e2->flt_sign;
|
res->flt_sign = e1->flt_sign ^ e2->flt_sign;
|
||||||
|
|
||||||
/* compute new exponent */
|
/* compute new exponent */
|
||||||
e3->flt_exp = e1->flt_exp + e2->flt_exp + 1;
|
res->flt_exp = e1->flt_exp + e2->flt_exp + 1;
|
||||||
|
|
||||||
/* 128 bit multiply of mantissas */
|
/* 128 bit multiply of mantissas */
|
||||||
|
|
||||||
|
@ -55,7 +50,7 @@ flt_mul(e1,e2,e3)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (result[0] & 0x8000)) {
|
if (! (result[0] & 0x8000)) {
|
||||||
e3->flt_exp--;
|
res->flt_exp--;
|
||||||
for (i = 0; i <= 3; i++) {
|
for (i = 0; i <= 3; i++) {
|
||||||
result[i] <<= 1;
|
result[i] <<= 1;
|
||||||
if (result[i+1]&0x8000) result[i] |= 1;
|
if (result[i+1]&0x8000) result[i] |= 1;
|
||||||
|
@ -65,16 +60,16 @@ flt_mul(e1,e2,e3)
|
||||||
/*
|
/*
|
||||||
* combine the registers to a total
|
* combine the registers to a total
|
||||||
*/
|
*/
|
||||||
e3->m1 = ((uint32_t)result[0] << 16) + result[1];
|
res->m1 = ((uint32_t)result[0] << 16) + result[1];
|
||||||
e3->m2 = ((uint32_t)result[2] << 16) + result[3];
|
res->m2 = ((uint32_t)result[2] << 16) + result[3];
|
||||||
if (result[4] & 0x8000) {
|
if (result[4] & 0x8000) {
|
||||||
if (++e3->m2 == 0) {
|
if (++res->m2 == 0) {
|
||||||
e3->m2 = 0;
|
res->m2 = 0;
|
||||||
if (++e3->m1 == 0) {
|
if (++res->m1 == 0) {
|
||||||
e3->m1 = 0x80000000;
|
res->m1 = 0x80000000;
|
||||||
e3->flt_exp++;
|
res->flt_exp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flt_chk(e3);
|
flt_chk(res);
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,118 +84,116 @@ for (i=1;i<20;i++) {
|
||||||
|
|
||||||
*/
|
*/
|
||||||
static flt_arith s10pow[] = { /* representation of 10 ** i */
|
static flt_arith s10pow[] = { /* representation of 10 ** i */
|
||||||
{ 0, 0, 0x80000000, 0 },
|
{ 0, 0, {0x80000000, 0} },
|
||||||
{ 0, 3, 0xA0000000, 0 },
|
{ 0, 3, {0xA0000000, 0} },
|
||||||
{ 0, 6, 0xC8000000, 0 },
|
{ 0, 6, {0xC8000000, 0} },
|
||||||
{ 0, 9, 0xFA000000, 0 },
|
{ 0, 9, {0xFA000000, 0} },
|
||||||
{ 0, 13, 0x9C400000, 0 },
|
{ 0, 13, {0x9C400000, 0} },
|
||||||
{ 0, 16, 0xC3500000, 0 },
|
{ 0, 16, {0xC3500000, 0} },
|
||||||
{ 0, 19, 0xF4240000, 0 },
|
{ 0, 19, {0xF4240000, 0} },
|
||||||
{ 0, 23, 0x98968000, 0 },
|
{ 0, 23, {0x98968000, 0} },
|
||||||
{ 0, 26, 0xBEBC2000, 0 },
|
{ 0, 26, {0xBEBC2000, 0} },
|
||||||
{ 0, 29, 0xEE6B2800, 0 },
|
{ 0, 29, {0xEE6B2800, 0} },
|
||||||
{ 0, 33, 0x9502F900, 0 },
|
{ 0, 33, {0x9502F900, 0} },
|
||||||
{ 0, 36, 0xBA43B740, 0 },
|
{ 0, 36, {0xBA43B740, 0} },
|
||||||
{ 0, 39, 0xE8D4A510, 0 },
|
{ 0, 39, {0xE8D4A510, 0} },
|
||||||
{ 0, 43, 0x9184E72A, 0 },
|
{ 0, 43, {0x9184E72A, 0} },
|
||||||
{ 0, 46, 0xB5E620F4, 0x80000000 },
|
{ 0, 46, {0xB5E620F4, 0x80000000} },
|
||||||
{ 0, 49, 0xE35FA931, 0xA0000000 },
|
{ 0, 49, {0xE35FA931, 0xA0000000} },
|
||||||
{ 0, 53, 0x8E1BC9BF, 0x04000000 },
|
{ 0, 53, {0x8E1BC9BF, 0x04000000} },
|
||||||
{ 0, 56, 0xB1A2BC2E, 0xC5000000 },
|
{ 0, 56, {0xB1A2BC2E, 0xC5000000} },
|
||||||
{ 0, 59, 0xDE0B6B3A, 0x76400000 },
|
{ 0, 59, {0xDE0B6B3A, 0x76400000} },
|
||||||
{ 0, 63, 0x8AC72304, 0x89E80000 },
|
{ 0, 63, {0x8AC72304, 0x89E80000} },
|
||||||
{ 0, 66, 0xAD78EBC5, 0xAC620000 },
|
{ 0, 66, {0xAD78EBC5, 0xAC620000} },
|
||||||
{ 0, 69, 0xD8D726B7, 0x177A8000 },
|
{ 0, 69, {0xD8D726B7, 0x177A8000} },
|
||||||
{ 0, 73, 0x87867832, 0x6EAC9000 },
|
{ 0, 73, {0x87867832, 0x6EAC9000} },
|
||||||
{ 0, 76, 0xA968163F, 0x0A57B400 },
|
{ 0, 76, {0xA968163F, 0x0A57B400} },
|
||||||
{ 0, 79, 0xD3C21BCE, 0xCCEDA100 },
|
{ 0, 79, {0xD3C21BCE, 0xCCEDA100} },
|
||||||
{ 0, 83, 0x84595161, 0x401484A0 },
|
{ 0, 83, {0x84595161, 0x401484A0} },
|
||||||
{ 0, 86, 0xA56FA5B9, 0x9019A5C8 },
|
{ 0, 86, {0xA56FA5B9, 0x9019A5C8} },
|
||||||
{ 0, 89, 0xCECB8F27, 0xF4200F3A }
|
{ 0, 89, {0xCECB8F27, 0xF4200F3A }}
|
||||||
};
|
};
|
||||||
static flt_arith big_10pow[] = { /* representation of 10 ** (28*i) */
|
static flt_arith big_10pow[] = { /* representation of 10 ** (28*i) */
|
||||||
{ 0, 0, 0x80000000, 0 },
|
{ 0, 0, {0x80000000, 0} },
|
||||||
{ 0, 93, 0x813F3978, 0xF8940984 },
|
{ 0, 93, {0x813F3978, 0xF8940984} },
|
||||||
{ 0, 186, 0x82818F12, 0x81ED44A0 },
|
{ 0, 186, {0x82818F12, 0x81ED44A0} },
|
||||||
{ 0, 279, 0x83C7088E, 0x1AAB65DB },
|
{ 0, 279, {0x83C7088E, 0x1AAB65DB} },
|
||||||
{ 0, 372, 0x850FADC0, 0x9923329E },
|
{ 0, 372, {0x850FADC0, 0x9923329E} },
|
||||||
{ 0, 465, 0x865B8692, 0x5B9BC5C2 },
|
{ 0, 465, {0x865B8692, 0x5B9BC5C2} },
|
||||||
{ 0, 558, 0x87AA9AFF, 0x79042287 },
|
{ 0, 558, {0x87AA9AFF, 0x79042287} },
|
||||||
{ 0, 651, 0x88FCF317, 0xF22241E2 },
|
{ 0, 651, {0x88FCF317, 0xF22241E2} },
|
||||||
{ 0, 744, 0x8A5296FF, 0xE33CC930 },
|
{ 0, 744, {0x8A5296FF, 0xE33CC930} },
|
||||||
{ 0, 837, 0x8BAB8EEF, 0xB6409C1A },
|
{ 0, 837, {0x8BAB8EEF, 0xB6409C1A} },
|
||||||
{ 0, 930, 0x8D07E334, 0x55637EB3 },
|
{ 0, 930, {0x8D07E334, 0x55637EB3} },
|
||||||
{ 0, 1023, 0x8E679C2F, 0x5E44FF8F },
|
{ 0, 1023, {0x8E679C2F, 0x5E44FF8F} },
|
||||||
{ 0, 1116, 0x8FCAC257, 0x558EE4E6 },
|
{ 0, 1116, {0x8FCAC257, 0x558EE4E6} },
|
||||||
{ 0, 1209, 0x91315E37, 0xDB165AA9 },
|
{ 0, 1209, {0x91315E37, 0xDB165AA9} },
|
||||||
{ 0, 1302, 0x929B7871, 0xDE7F22B9 },
|
{ 0, 1302, {0x929B7871, 0xDE7F22B9} },
|
||||||
{ 0, 1395, 0x940919BB, 0xD4620B6D },
|
{ 0, 1395, {0x940919BB, 0xD4620B6D} },
|
||||||
{ 0, 1488, 0x957A4AE1, 0xEBF7F3D4 },
|
{ 0, 1488, {0x957A4AE1, 0xEBF7F3D4} },
|
||||||
{ 0, 1581, 0x96EF14C6, 0x454AA840 },
|
{ 0, 1581, {0x96EF14C6, 0x454AA840} },
|
||||||
{ 0, 1674, 0x98678061, 0x27ECE4F5 },
|
{ 0, 1674, {0x98678061, 0x27ECE4F5} },
|
||||||
{ 0, 1767, 0x99E396C1, 0x3A3ACFF2 }
|
{ 0, 1767, {0x99E396C1, 0x3A3ACFF2} }
|
||||||
};
|
};
|
||||||
|
|
||||||
static flt_arith r_10pow[] = { /* representation of 10 ** -i */
|
static flt_arith r_10pow[] = { /* representation of 10 ** -i */
|
||||||
{ 0, 0, 0x80000000, 0 },
|
{ 0, 0, {0x80000000, 0} },
|
||||||
{ 0, -4, 0xCCCCCCCC, 0xCCCCCCCD },
|
{ 0, -4, {0xCCCCCCCC, 0xCCCCCCCD} },
|
||||||
{ 0, -7, 0xA3D70A3D, 0x70A3D70A },
|
{ 0, -7, {0xA3D70A3D, 0x70A3D70A} },
|
||||||
{ 0, -10, 0x83126E97, 0x8D4FDF3B },
|
{ 0, -10, {0x83126E97, 0x8D4FDF3B} },
|
||||||
{ 0, -14, 0xD1B71758, 0xE219652C },
|
{ 0, -14, {0xD1B71758, 0xE219652C} },
|
||||||
{ 0, -17, 0xA7C5AC47, 0x1B478423 },
|
{ 0, -17, {0xA7C5AC47, 0x1B478423} },
|
||||||
{ 0, -20, 0x8637BD05, 0xAF6C69B6 },
|
{ 0, -20, {0x8637BD05, 0xAF6C69B6} },
|
||||||
{ 0, -24, 0xD6BF94D5, 0xE57A42BC },
|
{ 0, -24, {0xD6BF94D5, 0xE57A42BC} },
|
||||||
{ 0, -27, 0xABCC7711, 0x8461CEFD },
|
{ 0, -27, {0xABCC7711, 0x8461CEFD} },
|
||||||
{ 0, -30, 0x89705F41, 0x36B4A597 },
|
{ 0, -30, {0x89705F41, 0x36B4A597} },
|
||||||
{ 0, -34, 0xDBE6FECE, 0xBDEDD5BF },
|
{ 0, -34, {0xDBE6FECE, 0xBDEDD5BF} },
|
||||||
{ 0, -37, 0xAFEBFF0B, 0xCB24AAFF },
|
{ 0, -37, {0xAFEBFF0B, 0xCB24AAFF} },
|
||||||
{ 0, -40, 0x8CBCCC09, 0x6F5088CC },
|
{ 0, -40, {0x8CBCCC09, 0x6F5088CC} },
|
||||||
{ 0, -44, 0xE12E1342, 0x4BB40E13 },
|
{ 0, -44, {0xE12E1342, 0x4BB40E13} },
|
||||||
{ 0, -47, 0xB424DC35, 0x095CD80F },
|
{ 0, -47, {0xB424DC35, 0x095CD80F} },
|
||||||
{ 0, -50, 0x901D7CF7, 0x3AB0ACD9 },
|
{ 0, -50, {0x901D7CF7, 0x3AB0ACD9} },
|
||||||
{ 0, -54, 0xE69594BE, 0xC44DE15B },
|
{ 0, -54, {0xE69594BE, 0xC44DE15B} },
|
||||||
{ 0, -57, 0xB877AA32, 0x36A4B449 },
|
{ 0, -57, {0xB877AA32, 0x36A4B449} },
|
||||||
{ 0, -60, 0x9392EE8E, 0x921D5D07 },
|
{ 0, -60, {0x9392EE8E, 0x921D5D07} },
|
||||||
{ 0, -64, 0xEC1E4A7D, 0xB69561A5 },
|
{ 0, -64, {0xEC1E4A7D, 0xB69561A5} },
|
||||||
{ 0, -67, 0xBCE50864, 0x92111AEB },
|
{ 0, -67, {0xBCE50864, 0x92111AEB} },
|
||||||
{ 0, -70, 0x971DA050, 0x74DA7BEF },
|
{ 0, -70, {0x971DA050, 0x74DA7BEF} },
|
||||||
{ 0, -74, 0xF1C90080, 0xBAF72CB1 },
|
{ 0, -74, {0xF1C90080, 0xBAF72CB1} },
|
||||||
{ 0, -77, 0xC16D9A00, 0x95928A27 },
|
{ 0, -77, {0xC16D9A00, 0x95928A27} },
|
||||||
{ 0, -80, 0x9ABE14CD, 0x44753B53 },
|
{ 0, -80, {0x9ABE14CD, 0x44753B53} },
|
||||||
{ 0, -84, 0xF79687AE, 0xD3EEC551 },
|
{ 0, -84, {0xF79687AE, 0xD3EEC551} },
|
||||||
{ 0, -87, 0xC6120625, 0x76589DDB },
|
{ 0, -87, {0xC6120625, 0x76589DDB} },
|
||||||
{ 0, -90, 0x9E74D1B7, 0x91E07E48 }
|
{ 0, -90, {0x9E74D1B7, 0x91E07E48} }
|
||||||
};
|
};
|
||||||
|
|
||||||
static flt_arith r_big_10pow[] = { /* representation of 10 ** -(28*i) */
|
static flt_arith r_big_10pow[] = { /* representation of 10 ** -(28*i) */
|
||||||
{ 0, 0, 0x80000000, 0 },
|
{ 0, 0, {0x80000000, 0} },
|
||||||
{ 0, -94, 0xFD87B5F2, 0x8300CA0E },
|
{ 0, -94, {0xFD87B5F2, 0x8300CA0E} },
|
||||||
{ 0, -187, 0xFB158592, 0xBE068D2F },
|
{ 0, -187, {0xFB158592, 0xBE068D2F} },
|
||||||
{ 0, -280, 0xF8A95FCF, 0x88747D94 },
|
{ 0, -280, {0xF8A95FCF, 0x88747D94} },
|
||||||
{ 0, -373, 0xF64335BC, 0xF065D37D },
|
{ 0, -373, {0xF64335BC, 0xF065D37D} },
|
||||||
{ 0, -466, 0xF3E2F893, 0xDEC3F126 },
|
{ 0, -466, {0xF3E2F893, 0xDEC3F126} },
|
||||||
{ 0, -559, 0xF18899B1, 0xBC3F8CA2 },
|
{ 0, -559, {0xF18899B1, 0xBC3F8CA2} },
|
||||||
{ 0, -652, 0xEF340A98, 0x172AACE5 },
|
{ 0, -652, {0xEF340A98, 0x172AACE5} },
|
||||||
{ 0, -745, 0xECE53CEC, 0x4A314EBE },
|
{ 0, -745, {0xECE53CEC, 0x4A314EBE} },
|
||||||
{ 0, -838, 0xEA9C2277, 0x23EE8BCB },
|
{ 0, -838, {0xEA9C2277, 0x23EE8BCB} },
|
||||||
{ 0, -931, 0xE858AD24, 0x8F5C22CA },
|
{ 0, -931, {0xE858AD24, 0x8F5C22CA} },
|
||||||
{ 0, -1024, 0xE61ACF03, 0x3D1A45DF },
|
{ 0, -1024, {0xE61ACF03, 0x3D1A45DF} },
|
||||||
{ 0, -1117, 0xE3E27A44, 0x4D8D98B8 },
|
{ 0, -1117, {0xE3E27A44, 0x4D8D98B8} },
|
||||||
{ 0, -1210, 0xE1AFA13A, 0xFBD14D6E },
|
{ 0, -1210, {0xE1AFA13A, 0xFBD14D6E} },
|
||||||
{ 0, -1303, 0xDF82365C, 0x497B5454 },
|
{ 0, -1303, {0xDF82365C, 0x497B5454} },
|
||||||
{ 0, -1396, 0xDD5A2C3E, 0xAB3097CC },
|
{ 0, -1396, {0xDD5A2C3E, 0xAB3097CC} },
|
||||||
{ 0, -1489, 0xDB377599, 0xB6074245 },
|
{ 0, -1489, {0xDB377599, 0xB6074245} },
|
||||||
{ 0, -1582, 0xD91A0545, 0xCDB51186 },
|
{ 0, -1582, {0xD91A0545, 0xCDB51186} },
|
||||||
{ 0, -1675, 0xD701CE3B, 0xD387BF48 },
|
{ 0, -1675, {0xD701CE3B, 0xD387BF48} },
|
||||||
{ 0, -1768, 0xD4EEC394, 0xD6258BF8 }
|
{ 0, -1768, {0xD4EEC394, 0xD6258BF8} }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BIGSZ (sizeof(big_10pow)/sizeof(big_10pow[0]))
|
#define BIGSZ (sizeof(big_10pow)/sizeof(big_10pow[0]))
|
||||||
#define SMALLSZ (sizeof(s10pow)/sizeof(s10pow[0]))
|
#define SMALLSZ (sizeof(s10pow)/sizeof(s10pow[0]))
|
||||||
|
|
||||||
static
|
static void add_exponent(register flt_arith *e, int exp)
|
||||||
add_exponent(e, exp)
|
|
||||||
register flt_arith *e;
|
|
||||||
{
|
{
|
||||||
int neg = exp < 0;
|
int neg = exp < 0;
|
||||||
int divsz, modsz;
|
int divsz, modsz;
|
||||||
|
@ -208,7 +206,7 @@ add_exponent(e, exp)
|
||||||
if (!status) status = flt_status;
|
if (!status) status = flt_status;
|
||||||
flt_mul(e, (neg ? r_10pow : s10pow) + modsz, &x);
|
flt_mul(e, (neg ? r_10pow : s10pow) + modsz, &x);
|
||||||
if (!status) status = flt_status;
|
if (!status) status = flt_status;
|
||||||
while (divsz >= BIGSZ) {
|
while (divsz >= (int)BIGSZ) {
|
||||||
flt_mul(&x, neg ? &r_big_10pow[BIGSZ-1] : &big_10pow[BIGSZ-1],&x);
|
flt_mul(&x, neg ? &r_big_10pow[BIGSZ-1] : &big_10pow[BIGSZ-1],&x);
|
||||||
if (!status) status = flt_status;
|
if (!status) status = flt_status;
|
||||||
divsz -= BIGSZ-1;
|
divsz -= BIGSZ-1;
|
||||||
|
@ -218,10 +216,7 @@ add_exponent(e, exp)
|
||||||
flt_status = status;
|
flt_status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void flt_str2flt(char *s, flt_arith *e)
|
||||||
flt_str2flt(s, e)
|
|
||||||
register char *s;
|
|
||||||
register flt_arith *e;
|
|
||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
int dotseen = 0;
|
int dotseen = 0;
|
||||||
|
@ -291,10 +286,7 @@ flt_str2flt(s, e)
|
||||||
|
|
||||||
#define NDIG 18
|
#define NDIG 18
|
||||||
|
|
||||||
static char *
|
static char *flt_ecvt(register flt_arith *e, int *decpt, int *sign)
|
||||||
flt_ecvt(e, decpt, sign)
|
|
||||||
register flt_arith *e;
|
|
||||||
int *decpt, *sign;
|
|
||||||
{
|
{
|
||||||
/* Like ecvt(), but for extended precision */
|
/* Like ecvt(), but for extended precision */
|
||||||
|
|
||||||
|
@ -420,10 +412,7 @@ flt_ecvt(e, decpt, sign)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void flt_flt2str(flt_arith *e, char *buf, int bufsize)
|
||||||
flt_flt2str(e, buf, bufsize)
|
|
||||||
flt_arith *e;
|
|
||||||
char *buf;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
int sign, dp;
|
int sign, dp;
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
|
|
||||||
#include "flt_misc.h"
|
#include "flt_misc.h"
|
||||||
|
|
||||||
void
|
void flt_umin(flt_arith *e)
|
||||||
flt_umin(e)
|
|
||||||
flt_arith *e;
|
|
||||||
{
|
{
|
||||||
/* Unary minus
|
/* Unary minus
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,6 +24,8 @@ struct tests {
|
||||||
{ 0, 0, 0, 0}
|
{ 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int dotest(register struct tests *p);
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
|
@ -37,9 +39,7 @@ main()
|
||||||
return exit_status;
|
return exit_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int dotest(register struct tests *p)
|
||||||
dotest(p)
|
|
||||||
register struct tests *p;
|
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
flt_arith e1, e2, e;
|
flt_arith e1, e2, e;
|
||||||
|
|
Loading…
Reference in a new issue