Probably does not work as intended

Bob W nospam at aol.com
Tue May 30 04:10:51 PDT 2006


"Jarrett Billingsley" <kb3ctd2 at yahoo.com> wrote in message 
news:e5gcr4$27r5$1 at digitaldaemon.com...
> I've been missing the ability to convert any base of string numerical 
> literal into an int (i.e. strtol()), so I wrote a new toInt that allows 
> any base from 2 to 36 (bases greater than 10 use a-z, case-insensitive). 
> It accomplishes this by using a translation table (generated by 
> std.string.maketrans() of course) for easy parsing.  It's written pretty 
> much the same way that the existing toInt is.

Unless you specifically intend to get identical results
for e. g.   toInt(";:=",16)   and   toInt("BAD",16) ,
you need to exclude a certain character range from
conversion.

Have a look at this one:

------------

int toInt(char[] s, int base) {
  const char XX=0xff;
  const char[256] transTable = [
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
     0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX,XX,XX,XX,XX,
    XX,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
    25,26,27,28,29,30,31,32,33,34,35,26,XX,XX,XX,XX,
    XX,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
    25,26,27,28,29,30,31,32,33,34,35,26,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,
    XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX,XX
  ];

  assert (base>0 && base<37);

  int length = s.length;
  if (!length)  throw new ConvError(s);

  uint minus = 0, v = 0;

  foreach (i, c; s) {
    char ct=transTable[c];

    if (ct<base) {
      uint v1 = v;
      v = v*base + ct;
      if (v<v1)  throw new ConvOverflowError(s);
    }

    else if (!i) {
      if (c == '-')       minus=1;
      else if (c != '+')  throw new ConvError(s);
    }

    else  throw new ConvError(s);
  }

  if (v & 0x80000000) {
    if (!minus)          throw new ConvOverflowError(s);
    if (v & 0x7fffffff)  throw new ConvOverflowError(s);
  }

  return cast(int)(minus ? 0-v : v);
}

-----------------

Please note that my sample program accepts a base of 1.
This is still a valid base but it probably has no practical
merits.





More information about the Digitalmars-d mailing list