diff options
| author | cremno <[email protected]> | 2015-02-13 09:33:03 +0100 |
|---|---|---|
| committer | cremno <[email protected]> | 2015-02-13 09:33:03 +0100 |
| commit | 6f893b5183450384e89b3d8f03f9ef32a7522624 (patch) | |
| tree | 481913e69c91974e18c4e2355ef7778f9f0ae93d /src/dump.c | |
| parent | 789177c8fe6c3bcb3833e76f95ecbd41b43b83fd (diff) | |
| download | mruby-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.c | 22 |
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: |
