mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* marshal.c (save_mantissa, load_mantissa): for interoperability
should count cut-down bit from topmost. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3713 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b4945ec141
commit
aede0cf378
2 changed files with 63 additions and 15 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Tue Apr 22 19:08:53 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
||||||
|
|
||||||
|
* marshal.c (save_mantissa, load_mantissa): for interoperability
|
||||||
|
should count cut-down bit from topmost.
|
||||||
|
|
||||||
Tue Apr 22 09:20:40 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Tue Apr 22 09:20:40 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* parse.y (arg_ambiguous): hopefully better message.
|
* parse.y (arg_ambiguous): hopefully better message.
|
||||||
|
|
73
marshal.c
73
marshal.c
|
@ -185,18 +185,47 @@ w_long(x, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DBL_MANT_DIG
|
#ifdef DBL_MANT_DIG
|
||||||
|
#define DECIMAL_MANT (53-16) /* from IEEE754 double precision */
|
||||||
|
|
||||||
|
#if DBL_MANT_DIG > 32
|
||||||
|
#define MANT_BITS 32
|
||||||
|
#elif DBL_MANT_DIG > 24
|
||||||
|
#define MANT_BITS 24
|
||||||
|
#elif DBL_MANT_DIG > 16
|
||||||
|
#define MANT_BITS 16
|
||||||
|
#else
|
||||||
|
#define MANT_BITS 8
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
save_mantissa(d, buf)
|
save_mantissa(d, buf)
|
||||||
double d;
|
double d;
|
||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
int e, m;
|
int e, i = 0;
|
||||||
|
unsigned long m;
|
||||||
|
double n;
|
||||||
|
|
||||||
m = (int)(modf(ldexp(frexp(fabs(d), &e), DBL_MANT_DIG - 16), &d) * 0x10000);
|
d = modf(ldexp(frexp(fabs(d), &e), DECIMAL_MANT), &d);
|
||||||
*buf++ = 0;
|
if (d > 0) {
|
||||||
*buf++ = m >> 8;
|
buf[i++] = 0;
|
||||||
*buf++ = m;
|
do {
|
||||||
return 3;
|
d = modf(ldexp(d, MANT_BITS), &n);
|
||||||
|
m = (unsigned long)n;
|
||||||
|
#if MANT_BITS > 24
|
||||||
|
buf[i++] = m >> 24;
|
||||||
|
#endif
|
||||||
|
#if MANT_BITS > 16
|
||||||
|
buf[i++] = m >> 16;
|
||||||
|
#endif
|
||||||
|
#if MANT_BITS > 8
|
||||||
|
buf[i++] = m >> 8;
|
||||||
|
#endif
|
||||||
|
buf[i++] = m;
|
||||||
|
} while (d > 0);
|
||||||
|
while (!buf[i - 1]) --i;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
|
@ -205,13 +234,29 @@ load_mantissa(d, buf, len)
|
||||||
const char *buf;
|
const char *buf;
|
||||||
int len;
|
int len;
|
||||||
{
|
{
|
||||||
if (len > 0) {
|
if (--len > 0 && !*buf++) { /* binary mantissa mark */
|
||||||
int e, s = d < 0, dig = len << 3;
|
int e, s = d < 0, dig = 0;
|
||||||
unsigned long m = 0;
|
unsigned long m;
|
||||||
|
|
||||||
modf(ldexp(frexp(fabs(d), &e), DBL_MANT_DIG - dig), &d);
|
modf(ldexp(frexp(fabs(d), &e), DECIMAL_MANT), &d);
|
||||||
do {m = (m << 8) | (*buf++ & 0xff);} while (--len);
|
do {
|
||||||
d = ldexp(frexp(d + ldexp((double)m, -dig), &dig), e);
|
m = 0;
|
||||||
|
switch (len) {
|
||||||
|
default: m = *buf++ & 0xff;
|
||||||
|
#if MANT_BITS > 24
|
||||||
|
case 3: m = (m << 8) | (*buf++ & 0xff);
|
||||||
|
#endif
|
||||||
|
#if MANT_BITS > 16
|
||||||
|
case 2: m = (m << 8) | (*buf++ & 0xff);
|
||||||
|
#endif
|
||||||
|
#if MANT_BITS > 8
|
||||||
|
case 1: m = (m << 8) | (*buf++ & 0xff);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
dig -= len < MANT_BITS / 8 ? 8 * (unsigned)len : MANT_BITS;
|
||||||
|
d += ldexp((double)m, dig);
|
||||||
|
} while ((len -= MANT_BITS / 8) > 0);
|
||||||
|
d = ldexp(d, e - DECIMAL_MANT);
|
||||||
if (s) d = -d;
|
if (s) d = -d;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
|
@ -983,9 +1028,7 @@ r_object0(arg, proc)
|
||||||
else {
|
else {
|
||||||
char *e;
|
char *e;
|
||||||
d = strtod(ptr, &e);
|
d = strtod(ptr, &e);
|
||||||
if (!*e++) {
|
d = load_mantissa(d, e, RSTRING(str)->len - (e - ptr));
|
||||||
d = load_mantissa(d, e, RSTRING(str)->len - (e - ptr));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
v = rb_float_new(d);
|
v = rb_float_new(d);
|
||||||
r_regist(v, arg);
|
r_regist(v, arg);
|
||||||
|
|
Loading…
Reference in a new issue