[Win32] set_str() ignores exponent iff base > 36
Sisyphus
sisyphus1 at optusnet.com.au
Mon Dec 10 04:05:17 CET 2007
----- Original Message -----
From: "Torbjorn Granlund" <tg at swox.com>
.
.
> Please try this patch. It should fix the bug, and also adds some
> error checking.
>
> *** mpf/set_str.c 30 Aug 2007 18:19:41 -0000
> --- mpf/set_str.c 9 Dec 2007 23:46:07 -0000
> *************** mpf_set_str (mpf_ptr x, const char *str,
> *** 272,277 ****
>
> if (expptr != 0)
> ! /* FIXME: Should do some error checking here. */
> ! exp_in_base = strtol (expptr, (char **) 0, exp_base);
> else
> exp_in_base = 0;
> --- 272,298 ----
>
> if (expptr != 0)
> ! {
> ! /* Scan and convert the exponent, in base exp_base. */
> ! long dig, neg = -(long) ('-' == expptr[0]);
> ! expptr -= neg; /* conditional increment */
> ! c = (unsigned char) *expptr++;
> ! dig = digit_value[c];
> ! if (dig >= exp_base)
> ! {
> ! TMP_FREE;
> ! return -1;
> ! }
> ! exp_in_base = dig;
> ! c = (unsigned char) *expptr++;
> ! dig = digit_value[c];
> ! while (dig < exp_base)
> ! {
> ! exp_in_base = exp_in_base * exp_base;
> ! exp_base += dig;
> ! c = (unsigned char) *expptr++;
> ! dig = digit_value[c];
> ! }
> ! exp_in_base = (exp_in_base ^ neg) - neg; /* conditional negation */
> ! }
> else
> exp_in_base = 0;
>
Yes - that seems to fix the bug quite nicely, though t-set_f.exe now fails
during the running of 'make check':
=====================================
wrong at data[6]
f_base -2, z_base 16
f "1 at 31" hex 0.4 at 8
want num 0x80000000
want den 0x1
got num 0x40000000
got den 0x1
This application has requested the Runtime to terminate it in an unusual
way.
Please contact the application's support team for more information.
FAIL: t-set_f.exe
=====================================
As regards Cygwin, 'man strtol' (as Paul suggested) indicates that allowable
bases are in the range 2..36. It doesn't actually *explicitly* state the
allowable range, but only ever mentions bases in the range 2..36.
The difference between Cygwin and MinGW seems to be that, on Cygwin,
strtol("z", (char**)0, 62) returns 35, whereas with MinGW it returns 0. Both
are "incorrect" (in that they don't return the expected value), but with
Cygwin one gets a result that at least allows mpf_set_str() to set a value
that *seems* sane (as long as you don't go looking too closely).
Thanks Torbjorn, Paul.
Cheers,
Rob
More information about the gmp-bugs
mailing list