summaryrefslogtreecommitdiff
path: root/marshal.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-21 03:26:00 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-21 03:26:00 +0000
commite207a3912ccb36defa8fa18f18648365a76b273d (patch)
tree9d28988bc7e61f07985e3cb1f7fd4907a7b0092f /marshal.c
parent0303a1ca43bb04ae0a62f83cf69c67ffa06b69bc (diff)
* marshal.c (w_float): use dtoa directly instead of stripping
needless trailing .0. * numeric.c (flo_to_s): reverted. [ruby-dev:41341] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27937 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'marshal.c')
-rw-r--r--marshal.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/marshal.c b/marshal.c
index 583b1c9152..0339e21f4c 100644
--- a/marshal.c
+++ b/marshal.c
@@ -354,7 +354,7 @@ load_mantissa(double d, const char *buf, long len)
static void
w_float(double d, struct dump_arg *arg)
{
- int ruby_dbl2cstr(double value, char *buf, int size);
+ char *ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
char buf[FLOAT_DIG + (DECIMAL_MANT + 7) / 8 + 10];
if (isinf(d)) {
@@ -369,9 +369,37 @@ w_float(double d, struct dump_arg *arg)
else w_cstr("0", arg);
}
else {
- int len = ruby_dbl2cstr(d, buf, (int)sizeof(buf));
- if (len > 2 && buf[len - 1] == '0' && buf[len - 2] == '.')
- len -= 2;
+ int decpt, sign, digs, len = 0;
+ char *e, *p = ruby_dtoa(d, 0, 0, &decpt, &sign, &e);
+ if (sign) buf[len++] = '-';
+ digs = (int)(e - p);
+ if (decpt < -3 || decpt > digs) {
+ buf[len++] = p[0];
+ buf[len++] = '.';
+ memcpy(buf + len, p + 1, --digs);
+ len += digs;
+ len += snprintf(buf + len, sizeof(buf) - len, "e%d", decpt - 1);
+ }
+ else if (decpt > 0) {
+ memcpy(buf + len, p, decpt);
+ len += decpt;
+ if ((digs -= decpt) > 0) {
+ buf[len++] = '.';
+ memcpy(buf + len, p + decpt, digs);
+ len += digs;
+ }
+ }
+ else {
+ buf[len++] = '0';
+ buf[len++] = '.';
+ if (decpt) {
+ memset(buf + len, '0', -decpt);
+ len -= decpt;
+ }
+ memcpy(buf + len, p, digs);
+ len += digs;
+ }
+ xfree(p);
w_bytes(buf, len, arg);
}
}