forked from M-Labs/artiq
runtime: implement round() (fixes #198).
From https://github.com/bpowers/musl/blob/master/src/math/round.c.
This commit is contained in:
parent
54aeb5030d
commit
d5216879d4
|
@ -17,6 +17,8 @@
|
|||
#include "dds.h"
|
||||
#include "rtio.h"
|
||||
|
||||
double round(double x);
|
||||
|
||||
void ksupport_abort(void);
|
||||
|
||||
int64_t now;
|
||||
|
@ -82,6 +84,9 @@ static const struct symbol runtime_exports[] = {
|
|||
{"__moddi3", &__moddi3},
|
||||
{"__powidf2", &__powidf2},
|
||||
|
||||
/* libm */
|
||||
{"round", &round},
|
||||
|
||||
/* exceptions */
|
||||
{"_Unwind_Resume", &_Unwind_Resume},
|
||||
{"__artiq_personality", &__artiq_personality},
|
||||
|
@ -118,6 +123,34 @@ static const struct symbol runtime_exports[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
double round(double x)
|
||||
{
|
||||
union {double f; uint64_t i;} u = {x};
|
||||
int e = u.i >> 52 & 0x7ff;
|
||||
double y;
|
||||
|
||||
if (e >= 0x3ff+52)
|
||||
return x;
|
||||
if (u.i >> 63)
|
||||
x = -x;
|
||||
if (e < 0x3ff-1) {
|
||||
/* we don't do it in ARTIQ */
|
||||
/* raise inexact if x!=0 */
|
||||
// FORCE_EVAL(x + 0x1p52);
|
||||
return 0*u.f;
|
||||
}
|
||||
y = (double)(x + 0x1p52) - 0x1p52 - x;
|
||||
if (y > 0.5)
|
||||
y = y + x - 1;
|
||||
else if (y <= -0.5)
|
||||
y = y + x + 1;
|
||||
else
|
||||
y = y + x;
|
||||
if (u.i >> 63)
|
||||
y = -y;
|
||||
return y;
|
||||
}
|
||||
|
||||
/* called by libunwind */
|
||||
int fprintf(FILE *stream, const char *fmt, ...)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue