* bignum.c (big2str_find_n1): removed extraneous element.

[ruby-dev:32351], [ruby-dev:32365]

* bignum.c (big2str_find_n1): returns necessary digits now.

* sprintf.c (remove_sign_bits): extends sign bit first.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14034 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2007-11-27 17:42:12 +00:00
Родитель 0cdd3bced5
Коммит 6eea7a7c71
3 изменённых файлов: 35 добавлений и 28 удалений

Просмотреть файл

@ -1,3 +1,12 @@
Wed Nov 28 02:42:10 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
* bignum.c (big2str_find_n1): removed extraneous element.
[ruby-dev:32351], [ruby-dev:32365]
* bignum.c (big2str_find_n1): returns necessary digits now.
* sprintf.c (remove_sign_bits): extends sign bit first.
Tue Nov 27 15:53:43 2007 Koichi Sasada <ko1@atdot.net> Tue Nov 27 15:53:43 2007 Koichi Sasada <ko1@atdot.net>
* compile.c (iseq_compile_each): "when *[],1" dumps core. * compile.c (iseq_compile_each): "when *[],1" dumps core.
@ -61,11 +70,6 @@ Mon Nov 26 23:18:46 2007 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
* test/drb/test_drb.rb (TestDRbEval): ignored. * test/drb/test_drb.rb (TestDRbEval): ignored.
Mon Nov 26 18:38:00 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
* sprintf.c (rb_str_format): always trim preceding zeros.
[ruby-dev:32351]
Mon Nov 26 17:32:16 2007 Tanaka Akira <akr@fsij.org> Mon Nov 26 17:32:16 2007 Tanaka Akira <akr@fsij.org>
* re.c (Init_Regexp): new method Regexp#fixed_encoding? * re.c (Init_Regexp): new method Regexp#fixed_encoding?

Просмотреть файл

@ -786,18 +786,18 @@ static long
big2str_find_n1(VALUE x, int base) big2str_find_n1(VALUE x, int base)
{ {
static const double log_2[] = { static const double log_2[] = {
1.0, 1.58496250072116, 2.0, 1.0, 1.58496250072116, 2.0,
2.32192809488736, 2.584962500721, 2.58496250072116, 2.32192809488736, 2.58496250072116, 2.8073549220576,
2.8073549220576, 3.0, 3.16992500144231, 3.0, 3.16992500144231, 3.32192809488736,
3.32192809488736, 3.4594316186373, 3.58496250072116, 3.4594316186373, 3.58496250072116, 3.70043971814109,
3.70043971814109, 3.8073549220576, 3.90689059560852, 3.8073549220576, 3.90689059560852, 4.0,
4.0, 4.08746284125034, 4.16992500144231, 4.08746284125034, 4.16992500144231, 4.24792751344359,
4.24792751344359, 4.32192809488736, 4.39231742277876, 4.32192809488736, 4.39231742277876, 4.4594316186373,
4.4594316186373, 4.52356195605701, 4.58496250072116, 4.52356195605701, 4.58496250072116, 4.64385618977472,
4.64385618977472, 4.70043971814109, 4.75488750216347, 4.70043971814109, 4.75488750216347, 4.8073549220576,
4.8073549220576, 4.85798099512757, 4.90689059560852, 4.85798099512757, 4.90689059560852, 4.95419631038688,
4.95419631038688, 5.0, 5.04439411935845, 5.0, 5.04439411935845, 5.08746284125034,
5.08746284125034, 5.12928301694497, 5.16992500144231 5.12928301694497, 5.16992500144231
}; };
long bits; long bits;
@ -814,7 +814,7 @@ big2str_find_n1(VALUE x, int base)
bits = BITSPERDIG*RBIGNUM_LEN(x); bits = BITSPERDIG*RBIGNUM_LEN(x);
} }
return (long)ceil(bits/(2*log_2[base - 2])); return (long)ceil(bits/log_2[base - 2]);
} }
static long static long
@ -898,7 +898,7 @@ rb_big2str0(VALUE x, int base, int trim)
{ {
int off; int off;
VALUE ss, xx; VALUE ss, xx;
long n1, len, hbase; long n1, n2, len, hbase;
char* ptr; char* ptr;
if (FIXNUM_P(x)) { if (FIXNUM_P(x)) {
@ -911,8 +911,9 @@ rb_big2str0(VALUE x, int base, int trim)
if (base < 2 && 36 < base) if (base < 2 && 36 < base)
rb_raise(rb_eArgError, "illegal radix %d", base); rb_raise(rb_eArgError, "illegal radix %d", base);
n1 = big2str_find_n1(x, base); n2 = big2str_find_n1(x, base);
ss = rb_str_new(0, 2*n1 + 1); /* plus one for sign */ n1 = (n2 + 1) / 2;
ss = rb_str_new(0, n2 + 1); /* plus one for sign */
ptr = RSTRING_PTR(ss); ptr = RSTRING_PTR(ss);
ptr[0] = RBIGNUM_SIGN(x) ? '+' : '-'; ptr[0] = RBIGNUM_SIGN(x) ? '+' : '-';
@ -924,11 +925,11 @@ rb_big2str0(VALUE x, int base, int trim)
xx = rb_big_clone(x); xx = rb_big_clone(x);
RBIGNUM_SET_SIGN(xx, 1); RBIGNUM_SET_SIGN(xx, 1);
if (n1 <= KARATSUBA_DIGITS) { if (n1 <= KARATSUBA_DIGITS) {
len = off + big2str_orig(xx, base, ptr + off, 2*n1, hbase, trim); len = off + big2str_orig(xx, base, ptr + off, n2, hbase, trim);
} }
else { else {
len = off + big2str_karatsuba(xx, base, ptr + off, n1, len = off + big2str_karatsuba(xx, base, ptr + off, n1,
2*n1, hbase, trim); n2, hbase, trim);
} }
ptr[len] = '\0'; ptr[len] = '\0';
@ -2442,7 +2443,7 @@ static VALUE
rb_big_odd_p(VALUE num) rb_big_odd_p(VALUE num)
{ {
if (BDIGITS(num)[0] & 1) { if (BDIGITS(num)[0] & 1) {
return Qtrue; return Qtrue;
} }
return Qfalse; return Qfalse;
} }
@ -2458,7 +2459,7 @@ static VALUE
rb_big_even_p(VALUE num) rb_big_even_p(VALUE num)
{ {
if (BDIGITS(num)[0] & 1) { if (BDIGITS(num)[0] & 1) {
return Qfalse; return Qfalse;
} }
return Qtrue; return Qtrue;
} }

Просмотреть файл

@ -19,6 +19,8 @@
#include <stdarg.h> #include <stdarg.h>
#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */ #define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */
#define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
#define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0 << (n)))
static void fmt_setup(char*,int,int,int,int); static void fmt_setup(char*,int,int,int,int);
@ -35,7 +37,7 @@ remove_sign_bits(char *str, int base)
} }
} }
else if (base == 8) { else if (base == 8) {
if (*t == '3') t++; *t |= EXTENDSIGN(3, strlen(t));
while (*t == '7') { while (*t == '7') {
t++; t++;
} }
@ -662,7 +664,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
val = rb_big_clone(val); val = rb_big_clone(val);
rb_big_2comp(val); rb_big_2comp(val);
} }
tmp1 = tmp = rb_big2str0(val, base, Qtrue); tmp1 = tmp = rb_big2str0(val, base, RBIGNUM_SIGN(val));
s = RSTRING_PTR(tmp); s = RSTRING_PTR(tmp);
if (*s == '-') { if (*s == '-') {
if (base == 10) { if (base == 10) {
@ -695,7 +697,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
if (*p == 'X') { if (*p == 'X') {
char *pp = s; char *pp = s;
int c; int c;
while (c = (int)*pp) { while ((c = (int)(unsigned char)*pp) != 0) {
*pp = rb_enc_toupper(c, enc); *pp = rb_enc_toupper(c, enc);
pp++; pp++;
} }