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