summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-10-30 02:24:08 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-10-30 02:24:08 +0000
commit720cfb3e6041746bc064924e900f8c26dd5626b0 (patch)
treeb29a36e3efcc00f7c4c2b71fda2df376462e70c0
parentaa1160ada856883c0bc3ca410efc7a5337bfc401 (diff)
* sprintf.c (rb_str_format): should preserve leading zero
information for negative %b and %x. [ruby-talk:221347] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@11236 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--bignum.c27
-rw-r--r--intern.h1
-rw-r--r--sprintf.c2
4 files changed, 24 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 33ea739505..f0c976f638 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Oct 30 11:15:40 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * sprintf.c (rb_str_format): should preserve leading zero
+ information for negative %b and %x. [ruby-talk:221347]
+
Thu Oct 26 21:05:58 2006 GOTOU Yuuzou <gotoyuzo@notwork.org>
* ext/openssl/ossl_pkcs7.c (ossl_pkcs7_verify): should clear error.
diff --git a/bignum.c b/bignum.c
index bc535fda04..50bd490e4e 100644
--- a/bignum.c
+++ b/bignum.c
@@ -614,15 +614,16 @@ rb_str2inum(str, base)
const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
VALUE
-rb_big2str(x, base)
+rb_big2str0(x, base, trim)
VALUE x;
int base;
+ int trim;
{
volatile VALUE t;
BDIGIT *ds;
long i, j, hbase;
VALUE ss;
- char *s, c;
+ char *s;
if (FIXNUM_P(x)) {
return rb_fix2str(x, base);
@@ -658,7 +659,7 @@ rb_big2str(x, base)
rb_raise(rb_eArgError, "illegal radix %d", base);
break;
}
- j += 2;
+ j++; /* space for sign */
hbase = base * base;
#if SIZEOF_BDIGITS > 2
@@ -667,11 +668,11 @@ rb_big2str(x, base)
t = rb_big_clone(x);
ds = BDIGITS(t);
- ss = rb_str_new(0, j);
+ ss = rb_str_new(0, j+1);
s = RSTRING(ss)->ptr;
s[0] = RBIGNUM(x)->sign ? '+' : '-';
- while (i && j) {
+ while (i && j > 1) {
long k = i;
BDIGIT_DBL num = 0;
@@ -680,16 +681,16 @@ rb_big2str(x, base)
ds[k] = (BDIGIT)(num / hbase);
num %= hbase;
}
- if (ds[i-1] == 0) i--;
+ if (trim && ds[i-1] == 0) i--;
k = SIZEOF_BDIGITS;
while (k--) {
- c = (char)(num % base);
- s[--j] = ruby_digitmap[(int)c];
+ s[--j] = ruby_digitmap[num % base];
num /= base;
- if (i == 0 && num == 0) break;
+ if (!trim && j < 1) break;
+ if (trim && i == 0 && num == 0) break;
}
}
- while (s[j] == '0') j++;
+ if (trim) {while (s[j] == '0') j++;}
RSTRING(ss)->len -= RBIGNUM(x)->sign?j:j-1;
memmove(RBIGNUM(x)->sign?s:s+1, s+j, RSTRING(ss)->len);
s[RSTRING(ss)->len] = '\0';
@@ -697,6 +698,12 @@ rb_big2str(x, base)
return ss;
}
+VALUE
+rb_big2str(VALUE x, int base)
+{
+ return rb_big2str0(x, base, Qtrue);
+}
+
/*
* call-seq:
* big.to_s(base=10) => string
diff --git a/intern.h b/intern.h
index 33a81ebe6e..13754b60b1 100644
--- a/intern.h
+++ b/intern.h
@@ -70,6 +70,7 @@ VALUE rb_str_to_inum _((VALUE, int, int));
VALUE rb_cstr2inum _((const char*, int));
VALUE rb_str2inum _((VALUE, int));
VALUE rb_big2str _((VALUE, int));
+VALUE rb_big2str0 _((VALUE, int, int));
long rb_big2long _((VALUE));
#define rb_big2int(x) rb_big2long(x)
unsigned long rb_big2ulong _((VALUE));
diff --git a/sprintf.c b/sprintf.c
index c29b9f9780..26142dea51 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -627,7 +627,7 @@ rb_f_sprintf(argc, argv)
val = rb_big_clone(val);
rb_big_2comp(val);
}
- tmp1 = tmp = rb_big2str(val, base);
+ tmp1 = tmp = rb_big2str0(val, base, RBIGNUM(val)->sign);
s = RSTRING(tmp)->ptr;
if (*s == '-') {
if (base == 10) {