summaryrefslogtreecommitdiffhomepage
path: root/src/dump.c
diff options
context:
space:
mode:
authorcremno <[email protected]>2015-02-13 09:33:03 +0100
committercremno <[email protected]>2015-02-13 09:33:03 +0100
commit6f893b5183450384e89b3d8f03f9ef32a7522624 (patch)
tree481913e69c91974e18c4e2355ef7778f9f0ae93d /src/dump.c
parent789177c8fe6c3bcb3833e76f95ecbd41b43b83fd (diff)
downloadmruby-6f893b5183450384e89b3d8f03f9ef32a7522624.tar.gz
mruby-6f893b5183450384e89b3d8f03f9ef32a7522624.zip
re-implement mrb_float_to_str()
The new implementation is backwards incompatible, but I couldn't find any usage outside mruby and I also couldn't think of a different and good name. All ISO C99 printf conversion specifiers for floating point numbers and an optional precision are supported. It is largely based on code from the MIT licensed musl libc (http://www.musl-libc.org/) and its floating point printing is exact (unlike the current code behind Float#to_s).
Diffstat (limited to 'src/dump.c')
-rw-r--r--src/dump.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/dump.c b/src/dump.c
index 24ddd90b8..3113a71d3 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -18,6 +18,12 @@
#ifdef ENABLE_STDIO
+#ifdef MRB_USE_FLOAT
+#define MRB_FLOAT_FMT "%.9e"
+#else
+#define MRB_FLOAT_FMT "%.16e"
+#endif
+
static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep);
#if UINT32_MAX > SIZE_MAX
@@ -111,7 +117,6 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
size_t size = 0;
size_t pool_no;
mrb_value str;
- char buf[32];
size += sizeof(uint32_t); /* plen */
size += irep->plen * (sizeof(uint8_t) + sizeof(uint16_t)); /* len(n) */
@@ -130,9 +135,9 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
break;
case MRB_TT_FLOAT:
+ str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
{
- int len;
- len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no]));
+ mrb_int len = RSTRING_LEN(str);
mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
size += (size_t)len;
}
@@ -163,7 +168,6 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
uint16_t len;
mrb_value str;
const char *char_ptr;
- char char_buf[30];
cur += uint32_to_bin(irep->plen, cur); /* number of pool */
@@ -186,13 +190,15 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
case MRB_TT_FLOAT:
cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
+ str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
+ char_ptr = RSTRING_PTR(str);
{
- int tlen;
- tlen = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no]));
- mrb_assert_int_fit(int, tlen, uint16_t, UINT16_MAX);
+ mrb_int tlen;
+
+ tlen = RSTRING_LEN(str);
+ mrb_assert_int_fit(mrb_int, tlen, uint16_t, UINT16_MAX);
len = (uint16_t)tlen;
}
- char_ptr = &char_buf[0];
break;
case MRB_TT_STRING: