mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
106 lines
3.5 KiB
Diff
106 lines
3.5 KiB
Diff
diff --git a/quickjs.c b/quickjs.c
|
|
index 7916013..3936eec 100644
|
|
--- a/quickjs.c
|
|
+++ b/quickjs.c
|
|
@@ -67,6 +67,16 @@
|
|
#define CONFIG_PRINTF_RNDN
|
|
#endif
|
|
|
|
+#ifdef CONFIG_PRINTF_RNDN
|
|
+#if !defined(FE_DOWNWARD) || !defined(FE_UPWARD)
|
|
+#ifdef CONFIG_BIGNUM
|
|
+#define CONFIG_DTOA_LIBBF
|
|
+#else
|
|
+#error "CONFIG_BIGNUM required if printf is RNDN and there is no fenv support"
|
|
+#endif
|
|
+#endif
|
|
+#endif
|
|
+
|
|
/* define to include Atomics.* operations which depend on the OS
|
|
threads */
|
|
#if !defined(EMSCRIPTEN)
|
|
@@ -11299,6 +11309,11 @@ static char *i64toa(char *buf_end, int64_t n, unsigned int base)
|
|
return q;
|
|
}
|
|
|
|
+/* maximum buffer size for js_dtoa */
|
|
+#define JS_DTOA_BUF_SIZE 128
|
|
+
|
|
+#ifndef CONFIG_DTOA_LIBBF
|
|
+
|
|
/* buf1 contains the printf result */
|
|
static void js_ecvt1(double d, int n_digits, int *decpt, int *sign, char *buf,
|
|
int rounding_mode, char *buf1, int buf1_size)
|
|
@@ -11318,9 +11333,6 @@ static void js_ecvt1(double d, int n_digits, int *decpt, int *sign, char *buf,
|
|
*decpt = atoi(buf1 + n_digits + 2 + (n_digits > 1)) + 1;
|
|
}
|
|
|
|
-/* maximum buffer size for js_dtoa */
|
|
-#define JS_DTOA_BUF_SIZE 128
|
|
-
|
|
/* needed because ecvt usually limits the number of digits to
|
|
17. Return the number of digits. */
|
|
static int js_ecvt(double d, int n_digits, int *decpt, int *sign, char *buf,
|
|
@@ -11429,6 +11441,8 @@ static void js_fcvt(char *buf, int buf_size, double d, int n_digits)
|
|
js_fcvt1(buf, buf_size, d, n_digits, rounding_mode);
|
|
}
|
|
|
|
+#endif /* CONFIG_DTOA_LIBBF */
|
|
+
|
|
/* radix != 10 is only supported with flags = JS_DTOA_VAR_FORMAT */
|
|
/* use as many digits as necessary */
|
|
#define JS_DTOA_VAR_FORMAT (0 << 0)
|
|
@@ -11442,8 +11456,10 @@ static void js_fcvt(char *buf, int buf_size, double d, int n_digits)
|
|
/* XXX: slow and maybe not fully correct. Use libbf when it is fast enough.
|
|
XXX: radix != 10 is only supported for small integers
|
|
*/
|
|
-static void js_dtoa1(char *buf, double d, int radix, int n_digits, int flags)
|
|
+static JSValue js_dtoa(JSContext *ctx,
|
|
+ double d, int radix, int n_digits, int flags)
|
|
{
|
|
+ char buf[JS_DTOA_BUF_SIZE];
|
|
char *q;
|
|
|
|
if (!isfinite(d)) {
|
|
@@ -11465,6 +11481,25 @@ static void js_dtoa1(char *buf, double d, int radix, int n_digits, int flags)
|
|
ptr = i64toa(buf1 + sizeof(buf1), i64, radix);
|
|
strcpy(buf, ptr);
|
|
} else {
|
|
+#ifdef CONFIG_DTOA_LIBBF
|
|
+ bf_flags_t bf_flags;
|
|
+ generic_conv:
|
|
+ bf_flags = BF_RNDNA;
|
|
+ switch (flags & 3) {
|
|
+ case JS_DTOA_VAR_FORMAT:
|
|
+ bf_flags |= BF_FTOA_FORMAT_FREE_MIN;
|
|
+ break;
|
|
+ case JS_DTOA_FIXED_FORMAT:
|
|
+ bf_flags |= BF_FTOA_FORMAT_FIXED;
|
|
+ break;
|
|
+ case JS_DTOA_FRAC_FORMAT:
|
|
+ bf_flags |= BF_FTOA_FORMAT_FRAC;
|
|
+ break;
|
|
+ }
|
|
+ if (flags & JS_DTOA_FORCE_EXP)
|
|
+ bf_flags |= BF_FTOA_FORCE_EXP;
|
|
+ return js_ftoa(ctx, JS_NewFloat64(ctx, d), radix, n_digits, bf_flags);
|
|
+#else /* CONFIG_DTOA_LIBBF */
|
|
if (d == 0.0)
|
|
d = 0.0; /* convert -0 to 0 */
|
|
if (flags == JS_DTOA_FRAC_FORMAT) {
|
|
@@ -11528,14 +11563,8 @@ static void js_dtoa1(char *buf, double d, int radix, int n_digits, int flags)
|
|
sprintf(q, "%d", p);
|
|
}
|
|
}
|
|
+#endif /* CONFIG_DTOA_LIBBF */
|
|
}
|
|
-}
|
|
-
|
|
-static JSValue js_dtoa(JSContext *ctx,
|
|
- double d, int radix, int n_digits, int flags)
|
|
-{
|
|
- char buf[JS_DTOA_BUF_SIZE];
|
|
- js_dtoa1(buf, d, radix, n_digits, flags);
|
|
return JS_NewString(ctx, buf);
|
|
}
|
|
|