mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c (rb_cstr_to_inum, rb_big2str): allow 2-36 as radix.
* numeric.c (rb_fix2str): ditto. * string.c (rb_str_to_i): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3677 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d39d90f86a
commit
3f4472433d
5 changed files with 98 additions and 69 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Mon Apr 14 15:54:18 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
||||||
|
|
||||||
|
* bignum.c (rb_cstr_to_inum, rb_big2str): allow 2-36 as radix.
|
||||||
|
|
||||||
|
* numeric.c (rb_fix2str): ditto.
|
||||||
|
|
||||||
|
* string.c (rb_str_to_i): ditto.
|
||||||
|
|
||||||
Sun Apr 13 03:20:31 2003 WATANABE Hirofumi <eban@ruby-lang.org>
|
Sun Apr 13 03:20:31 2003 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||||
|
|
||||||
* lib/mkmf.rb (try_func): remove COMMON_HEADERS at first for
|
* lib/mkmf.rb (try_func): remove COMMON_HEADERS at first for
|
||||||
|
|
120
bignum.c
120
bignum.c
|
@ -375,17 +375,22 @@ rb_cstr_to_inum(str, base, badcheck)
|
||||||
str += 2;
|
str += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
len = 2;
|
||||||
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
len = 3;
|
|
||||||
if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
|
if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
|
||||||
str += 2;
|
str += 2;
|
||||||
}
|
}
|
||||||
|
case 4: case 5: case 6: case 7:
|
||||||
|
len = 3;
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
len = 4;
|
|
||||||
if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
|
if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
|
||||||
str += 2;
|
str += 2;
|
||||||
}
|
}
|
||||||
|
case 11: case 12: case 13: case 14: case 15:
|
||||||
|
len = 4;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
len = 4;
|
len = 4;
|
||||||
|
@ -393,6 +398,17 @@ rb_cstr_to_inum(str, base, badcheck)
|
||||||
str += 2;
|
str += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
if (base < 2 || 36 < base) {
|
||||||
|
rb_raise(rb_eArgError, "illegal radix %d", base);
|
||||||
|
}
|
||||||
|
if (base <= 32) {
|
||||||
|
len = 5;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
len = 6;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (*str == '0') { /* squeeze preceeding 0s */
|
if (*str == '0') { /* squeeze preceeding 0s */
|
||||||
while (*++str == '0');
|
while (*++str == '0');
|
||||||
|
@ -407,10 +423,7 @@ rb_cstr_to_inum(str, base, badcheck)
|
||||||
if (badcheck) {
|
if (badcheck) {
|
||||||
if (end == str) goto bad; /* no number */
|
if (end == str) goto bad; /* no number */
|
||||||
while (*end && ISSPACE(*end)) end++;
|
while (*end && ISSPACE(*end)) end++;
|
||||||
if (*end) { /* trailing garbage */
|
if (*end) goto bad; /* trailing garbage */
|
||||||
bad:
|
|
||||||
rb_invalid_str(s, "Integer");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (POSFIXABLE(val)) {
|
if (POSFIXABLE(val)) {
|
||||||
|
@ -434,42 +447,27 @@ rb_cstr_to_inum(str, base, badcheck)
|
||||||
zds = BDIGITS(z);
|
zds = BDIGITS(z);
|
||||||
for (i=len;i--;) zds[i]=0;
|
for (i=len;i--;) zds[i]=0;
|
||||||
while (c = *str++) {
|
while (c = *str++) {
|
||||||
switch (c) {
|
if (c == '_') {
|
||||||
case '8': case '9':
|
|
||||||
if (base == 8) {
|
|
||||||
c = base;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
|
||||||
case '5': case '6': case '7':
|
|
||||||
c = c - '0';
|
|
||||||
nondigit = 0;
|
|
||||||
break;
|
|
||||||
case 'a': case 'b': case 'c':
|
|
||||||
case 'd': case 'e': case 'f':
|
|
||||||
c -= 'a' - 'A';
|
|
||||||
case 'A': case 'B': case 'C':
|
|
||||||
case 'D': case 'E': case 'F':
|
|
||||||
if (base != 16) {
|
|
||||||
nondigit = c;
|
|
||||||
c = base;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c = c - 'A' + 10;
|
|
||||||
nondigit = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '_':
|
|
||||||
if (badcheck) {
|
if (badcheck) {
|
||||||
if (nondigit) goto bad;
|
if (nondigit) goto bad;
|
||||||
nondigit = c;
|
nondigit = c;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
default:
|
}
|
||||||
c = base;
|
else if (isdigit(c)) {
|
||||||
|
c -= '0';
|
||||||
|
}
|
||||||
|
else if (islower(c)) {
|
||||||
|
c -= 'a' - 10;
|
||||||
|
}
|
||||||
|
else if (isupper(c)) {
|
||||||
|
c -= 'A' - 10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (c >= base) break;
|
if (c >= base) break;
|
||||||
|
nondigit = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
num = c;
|
num = c;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -489,7 +487,10 @@ rb_cstr_to_inum(str, base, badcheck)
|
||||||
str--;
|
str--;
|
||||||
if (s+1 < str && str[-1] == '_') goto bad;
|
if (s+1 < str && str[-1] == '_') goto bad;
|
||||||
while (*str && ISSPACE(*str)) str++;
|
while (*str && ISSPACE(*str)) str++;
|
||||||
if (*str) goto bad;
|
if (*str) {
|
||||||
|
bad:
|
||||||
|
rb_invalid_str(s, "Integer");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bignorm(z);
|
return bignorm(z);
|
||||||
|
@ -598,7 +599,7 @@ rb_str2inum(str, base)
|
||||||
return rb_str_to_inum(str, base, base==0);
|
return rb_str_to_inum(str, base, base==0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char hexmap[] = "0123456789abcdef";
|
const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
VALUE
|
VALUE
|
||||||
rb_big2str(x, base)
|
rb_big2str(x, base)
|
||||||
VALUE x;
|
VALUE x;
|
||||||
|
@ -617,25 +618,36 @@ rb_big2str(x, base)
|
||||||
if (BIGZEROP(x)) {
|
if (BIGZEROP(x)) {
|
||||||
return rb_str_new2("0");
|
return rb_str_new2("0");
|
||||||
}
|
}
|
||||||
if (base == 10) {
|
j = SIZEOF_BDIGITS*CHAR_BIT*i;
|
||||||
j = (SIZEOF_BDIGITS/sizeof(char)*CHAR_BIT*i*241L)/800+2;
|
switch (base) {
|
||||||
hbase = 10000;
|
case 2: break;
|
||||||
}
|
case 3:
|
||||||
else if (base == 16) {
|
j = j * 647L / 1024;
|
||||||
j = (SIZEOF_BDIGITS/sizeof(char)*CHAR_BIT*i)/4+2;
|
break;
|
||||||
hbase = 0x10000;
|
case 4: case 5: case 6: case 7:
|
||||||
}
|
j /= 2;
|
||||||
else if (base == 8) {
|
break;
|
||||||
j = (SIZEOF_BDIGITS/sizeof(char)*CHAR_BIT*i)+2;
|
case 8: case 9:
|
||||||
hbase = 010000;
|
j /= 3;
|
||||||
}
|
break;
|
||||||
else if (base == 2) {
|
case 10: case 11: case 12: case 13: case 14: case 15:
|
||||||
j = (SIZEOF_BDIGITS*CHAR_BIT*i)+2;
|
j = j * 241L / 800;
|
||||||
hbase = 020;
|
break;
|
||||||
}
|
case 16: case 17: case 18: case 19: case 20: case 21:
|
||||||
else {
|
case 22: case 23: case 24: case 25: case 26: case 27:
|
||||||
|
case 28: case 29: case 30: case 31:
|
||||||
|
j /= 4;
|
||||||
|
break;
|
||||||
|
case 32: case 33: case 34: case 35: case 36:
|
||||||
|
j /= 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
rb_raise(rb_eArgError, "illegal radix %d", base);
|
rb_raise(rb_eArgError, "illegal radix %d", base);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
j += 2;
|
||||||
|
hbase = base * base;
|
||||||
|
hbase *= hbase;
|
||||||
|
|
||||||
t = rb_big_clone(x);
|
t = rb_big_clone(x);
|
||||||
ds = BDIGITS(t);
|
ds = BDIGITS(t);
|
||||||
|
@ -656,7 +668,7 @@ rb_big2str(x, base)
|
||||||
k = 4;
|
k = 4;
|
||||||
while (k--) {
|
while (k--) {
|
||||||
c = (char)(num % base);
|
c = (char)(num % base);
|
||||||
s[--j] = hexmap[(int)c];
|
s[--j] = ruby_digitmap[(int)c];
|
||||||
num /= base;
|
num /= base;
|
||||||
if (i == 0 && num == 0) break;
|
if (i == 0 && num == 0) break;
|
||||||
}
|
}
|
||||||
|
|
27
numeric.c
27
numeric.c
|
@ -1178,21 +1178,30 @@ rb_fix2str(x, base)
|
||||||
VALUE x;
|
VALUE x;
|
||||||
int base;
|
int base;
|
||||||
{
|
{
|
||||||
char fmt[4], buf[22], *b = buf;
|
extern const char ruby_digitmap[];
|
||||||
|
char buf[SIZEOF_LONG*CHAR_BIT/2 + 2], *b = buf + sizeof buf;
|
||||||
long val = FIX2LONG(x);
|
long val = FIX2LONG(x);
|
||||||
|
int neg = 0;
|
||||||
|
|
||||||
fmt[0] = '%'; fmt[1] = 'l'; fmt[3] = '\0';
|
if (base < 2 || 36 < base) {
|
||||||
if (base == 10) fmt[2] = 'd';
|
rb_raise(rb_eArgError, "illegal radix %d", base);
|
||||||
else if (base == 16) fmt[2] = 'x';
|
}
|
||||||
else if (base == 8) fmt[2] = 'o';
|
if (val == 0) {
|
||||||
else rb_raise(rb_eArgError, "illegal radix %d", base);
|
return rb_str_new2("0");
|
||||||
|
}
|
||||||
if (val < 0) {
|
if (val < 0) {
|
||||||
val = -val;
|
val = -val;
|
||||||
*b++ = '-';
|
neg = 1;
|
||||||
|
}
|
||||||
|
*--b = '\0';
|
||||||
|
do {
|
||||||
|
*--b = ruby_digitmap[(int)(val % base)];
|
||||||
|
} while (val /= base);
|
||||||
|
if (neg) {
|
||||||
|
*--b = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(b, fmt, val);
|
return rb_str_new2(b);
|
||||||
return rb_str_new2(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
|
|
@ -1181,6 +1181,12 @@ s = <<EOS
|
||||||
}
|
}
|
||||||
EOS
|
EOS
|
||||||
test_ok(s == "1,2,3\n")
|
test_ok(s == "1,2,3\n")
|
||||||
|
test_ok("Just".to_i(36) == 926381)
|
||||||
|
test_ok("-another".to_i(36) == -23200231779)
|
||||||
|
test_ok(1299022.to_s(36) == "ruby")
|
||||||
|
test_ok(-1045307475.to_s(36) == "-hacker")
|
||||||
|
test_ok("Just_another_Ruby_hacker".to_i(36) == 265419172580680477752431643787347)
|
||||||
|
test_ok(-265419172580680477752431643787347.to_s(36) == "-justanotherrubyhacker")
|
||||||
|
|
||||||
test_check "assignment"
|
test_check "assignment"
|
||||||
a = nil
|
a = nil
|
||||||
|
|
6
string.c
6
string.c
|
@ -1836,12 +1836,6 @@ rb_str_to_i(argc, argv, str)
|
||||||
if (argc == 0) base = 10;
|
if (argc == 0) base = 10;
|
||||||
else base = NUM2INT(b);
|
else base = NUM2INT(b);
|
||||||
|
|
||||||
switch (base) {
|
|
||||||
case 0: case 2: case 8: case 10: case 16:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rb_raise(rb_eArgError, "illegal radix %d", base);
|
|
||||||
}
|
|
||||||
return rb_str_to_inum(str, base, Qfalse);
|
return rb_str_to_inum(str, base, Qfalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue