83 lines
1.8 KiB
C
83 lines
1.8 KiB
C
|
/*
|
||
|
* Replacements for missing platform functions.
|
||
|
*
|
||
|
* Unlike the originals, fpclassify() and signbit() replacements don't
|
||
|
* work on any floating point types, only doubles. The C typing here
|
||
|
* mimics the standard prototypes.
|
||
|
*/
|
||
|
|
||
|
#include "duk_internal.h"
|
||
|
|
||
|
#if defined(DUK_USE_COMPUTED_NAN)
|
||
|
DUK_INTERNAL double duk_computed_nan;
|
||
|
#endif
|
||
|
|
||
|
#if defined(DUK_USE_COMPUTED_INFINITY)
|
||
|
DUK_INTERNAL double duk_computed_infinity;
|
||
|
#endif
|
||
|
|
||
|
#if defined(DUK_USE_REPL_FPCLASSIFY)
|
||
|
DUK_INTERNAL int duk_repl_fpclassify(double x) {
|
||
|
duk_double_union u;
|
||
|
duk_uint_fast16_t expt;
|
||
|
duk_small_int_t mzero;
|
||
|
|
||
|
u.d = x;
|
||
|
expt = (duk_uint_fast16_t) (u.us[DUK_DBL_IDX_US0] & 0x7ff0UL);
|
||
|
if (expt > 0x0000UL && expt < 0x7ff0UL) {
|
||
|
/* expt values [0x001,0x7fe] = normal */
|
||
|
return DUK_FP_NORMAL;
|
||
|
}
|
||
|
|
||
|
mzero = (u.ui[DUK_DBL_IDX_UI1] == 0 && (u.ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) == 0);
|
||
|
if (expt == 0x0000UL) {
|
||
|
/* expt 0x000 is zero/subnormal */
|
||
|
if (mzero) {
|
||
|
return DUK_FP_ZERO;
|
||
|
} else {
|
||
|
return DUK_FP_SUBNORMAL;
|
||
|
}
|
||
|
} else {
|
||
|
/* expt 0xfff is infinite/nan */
|
||
|
if (mzero) {
|
||
|
return DUK_FP_INFINITE;
|
||
|
} else {
|
||
|
return DUK_FP_NAN;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined(DUK_USE_REPL_SIGNBIT)
|
||
|
DUK_INTERNAL int duk_repl_signbit(double x) {
|
||
|
duk_double_union u;
|
||
|
u.d = x;
|
||
|
return (int) (u.uc[DUK_DBL_IDX_UC0] & 0x80UL);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined(DUK_USE_REPL_ISFINITE)
|
||
|
DUK_INTERNAL int duk_repl_isfinite(double x) {
|
||
|
int c = DUK_FPCLASSIFY(x);
|
||
|
if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {
|
||
|
return 0;
|
||
|
} else {
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined(DUK_USE_REPL_ISNAN)
|
||
|
DUK_INTERNAL int duk_repl_isnan(double x) {
|
||
|
int c = DUK_FPCLASSIFY(x);
|
||
|
return (c == DUK_FP_NAN);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined(DUK_USE_REPL_ISINF)
|
||
|
DUK_INTERNAL int duk_repl_isinf(double x) {
|
||
|
int c = DUK_FPCLASSIFY(x);
|
||
|
return (c == DUK_FP_INFINITE);
|
||
|
}
|
||
|
#endif
|