aboutsummaryrefslogtreecommitdiffstats
path: root/extension/rwarray.c
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2021-12-08 10:05:06 -0500
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2021-12-08 10:05:06 -0500
commit09e98ee95fb453adc0f1783937477cd065611581 (patch)
treec84a03093233653d7a2a315c259083afc9bd0051 /extension/rwarray.c
parente03c8822c48bedfe6cc7fbd5a9382d9630de6494 (diff)
downloadegawk-09e98ee95fb453adc0f1783937477cd065611581.tar.gz
egawk-09e98ee95fb453adc0f1783937477cd065611581.tar.bz2
egawk-09e98ee95fb453adc0f1783937477cd065611581.zip
In extension rwarray, write and read mpfr values as strings instead of using the new and experimental floating-point interchange format.
Diffstat (limited to 'extension/rwarray.c')
-rw-r--r--extension/rwarray.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/extension/rwarray.c b/extension/rwarray.c
index 9a8d15e9..1356005c 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -313,7 +313,22 @@ write_number(FILE *fp, awk_value_t *val)
if (fwrite(& code, 1, sizeof(code), fp) != sizeof(code))
return awk_false;
+#ifdef USE_MPFR_FPIF
+ /* This would be preferable, but it is not available
+ * on older platforms with mpfr 3.x. It's also marked
+ * experimental in mpfr 4.1, so perhaps not ready for
+ * production use yet. */
if (mpfr_fpif_export(fp, val->num_ptr) != 0)
+#else
+#define MPFR_STR_BASE 62 /* maximize base to minimize string len */
+#define MPFR_STR_ROUND MPFR_RNDN
+ /* XXX does the choice of MPFR_RNDN matter, given
+ * that the precision is 0, so we should be rendering
+ * in full precision? */
+ /* We need to write a terminating space, since
+ * mpfr_inp_str reads until it hits a space or EOF */
+ if ((mpfr_out_str(fp, MPFR_STR_BASE, 0, val->num_ptr, MPFR_STR_ROUND) == 0) || (putc(' ', fp) == EOF))
+#endif
return awk_false;
} else {
code = htonl(VT_GMP);
@@ -595,7 +610,14 @@ read_number(FILE *fp, awk_value_t *value, uint32_t code)
mpfr_t mpfr_val;
mpfr_init(mpfr_val);
+#ifdef USE_MPFR_FPIF
+ /* preferable if widely available and stable */
if (mpfr_fpif_import(mpfr_val, fp) != 0)
+#else
+ /* N.B. need to consume the terminating space we wrote
+ * after mpfr_out_str */
+ if ((mpfr_inp_str(mpfr_val, fp, MPFR_STR_BASE, MPFR_STR_ROUND) == 0) || (getc(fp) != ' '))
+#endif
return awk_false;
value = make_number_mpfr(& mpfr_val, value);