[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