summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-06-10 10:15:00 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-06-10 10:15:00 +0000
commit58c1c90731375eafa6cbe438eb9dc85945a6358e (patch)
treea545d7babf5822309cca2c3df3375c0ed2641f2d /numeric.c
parent11c11e9b468c11a5a61ea1239ed57e635f910558 (diff)
* numeric.c (fix_lshift): negative shift count means right shift.
(ruby-bugs-ja:PR#248) * numeric.c (fix_rshift): return -1 when left side operand is negative. (ruby-bugs-ja:PR#247) * parse.y (yylex): `0_' should be an error. (ruby-bugs-ja:PR#239) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@2536 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/numeric.c b/numeric.c
index 7dc46c0487..ff946720c1 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1264,6 +1264,8 @@ fix_xor(x, y)
return rb_int2inum(val);
}
+static VALUE fix_rshift _((VALUE, VALUE));
+
static VALUE
fix_lshift(x, y)
VALUE x, y;
@@ -1272,6 +1274,8 @@ fix_lshift(x, y)
val = NUM2LONG(x);
width = NUM2LONG(y);
+ if (width < 0)
+ return fix_rshift(x, INT2FIX(-width));
if (width > (sizeof(VALUE)*CHAR_BIT-1)
|| ((unsigned long)val)>>(sizeof(VALUE)*CHAR_BIT-1-width) > 0) {
return rb_big_lshift(rb_int2big(val), y);
@@ -1290,11 +1294,12 @@ fix_rshift(x, y)
if (i < 0)
return fix_lshift(x, INT2FIX(-i));
if (i == 0) return x;
+ val = FIX2LONG(x);
if (i >= sizeof(long)*CHAR_BIT-1) {
- if (i < 0) return INT2FIX(-1);
+ if (val < 0) return INT2FIX(-1);
return INT2FIX(0);
}
- val = RSHIFT(FIX2LONG(x), i);
+ val = RSHIFT(val, i);
return INT2FIX(val);
}