Feature #8738 ยป single_bit_p.patch
bignum.c (working copy) | ||
---|---|---|
}
|
||
/*
|
||
* call-seq:
|
||
* big.single_bit? -> true or false
|
||
*
|
||
* Returns true if abs(fixnum) has exactly a single one bit in binary format.
|
||
* In other words, it returns true if the number is a power of two.
|
||
*
|
||
* (-2**100-1).single_bit? #=> false
|
||
* (-2**100).single_bit? #=> true
|
||
* (-2**100+1).single_bit? #=> false
|
||
* (2**100-1).single_bit? #=> false
|
||
* (2**100).single_bit? #=> true
|
||
* (2**100+1).single_bit? #=> false
|
||
*
|
||
*/
|
||
static VALUE
|
||
rb_big_single_bit_p(VALUE num)
|
||
{
|
||
long n;
|
||
BDIGIT *ds, d;
|
||
ds = BDIGITS(num);
|
||
n = RBIGNUM_LEN(num);
|
||
while (0 < n) {
|
||
--n;
|
||
d = ds[n];
|
||
if (d != 0) {
|
||
if (d & (d-1))
|
||
return Qfalse;
|
||
goto single_bit_word_found;
|
||
}
|
||
}
|
||
return Qfalse;
|
||
single_bit_word_found:
|
||
while (0 < n) {
|
||
--n;
|
||
if (ds[n] != 0) {
|
||
return Qfalse;
|
||
}
|
||
}
|
||
return Qtrue;
|
||
}
|
||
/*
|
||
* Bignum objects hold integers outside the range of
|
||
* Fixnum. Bignum objects are created
|
||
* automatically when integer calculations would otherwise overflow a
|
||
... | ... | |
rb_define_method(rb_cBignum, "size", rb_big_size, 0);
|
||
rb_define_method(rb_cBignum, "odd?", rb_big_odd_p, 0);
|
||
rb_define_method(rb_cBignum, "even?", rb_big_even_p, 0);
|
||
rb_define_method(rb_cBignum, "single_bit?", rb_big_single_bit_p, 0);
|
||
power_cache_init();
|
||
}
|
test/ruby/test_integer.rb (working copy) | ||
---|---|---|
end
|
||
assert_equal(3 ^ 10, 3 ^ obj)
|
||
end
|
||
def test_single_bit?
|
||
assert_equal(false,-5.single_bit?)
|
||
assert_equal(true ,-4.single_bit?)
|
||
assert_equal(false,-3.single_bit?)
|
||
assert_equal(true ,-2.single_bit?)
|
||
assert_equal(true ,-1.single_bit?)
|
||
assert_equal(false, 0.single_bit?)
|
||
assert_equal(true, 1.single_bit?)
|
||
assert_equal(true, 2.single_bit?)
|
||
assert_equal(false, 3.single_bit?)
|
||
assert_equal(true, 4.single_bit?)
|
||
assert_equal(false, 5.single_bit?)
|
||
assert_equal(false, (3*2**128).single_bit?)
|
||
2.upto(200) {|i|
|
||
n = 2**i
|
||
assert_equal(false, (n-1).single_bit?)
|
||
assert_equal(true , n.single_bit?)
|
||
assert_equal(false, (n+1).single_bit?)
|
||
n = -n
|
||
assert_equal(false, (n-1).single_bit?)
|
||
assert_equal(true , n.single_bit?)
|
||
assert_equal(false, (n+1).single_bit?)
|
||
}
|
||
end
|
||
end
|
numeric.c (working copy) | ||
---|---|---|
/*
|
||
* call-seq:
|
||
* fixnum.single_bit? -> true or false
|
||
*
|
||
* Returns true if abs(fixnum) has exactly a single one bit in binary format.
|
||
* In other words, it returns true if the number is a power of two.
|
||
* I.e. it returns true for 1, 2, 4, 8, ... and
|
||
* -1, -2, -4, -8, ...
|
||
*
|
||
* -9.single_bit? #=> false
|
||
* -8.single_bit? #=> true
|
||
* -7.single_bit? #=> false
|
||
* -6.single_bit? #=> false
|
||
* -5.single_bit? #=> false
|
||
* -4.single_bit? #=> true
|
||
* -3.single_bit? #=> false
|
||
* -2.single_bit? #=> true
|
||
* -1.single_bit? #=> true
|
||
* 0.single_bit? #=> false
|
||
* 1.single_bit? #=> true
|
||
* 2.single_bit? #=> true
|
||
* 3.single_bit? #=> false
|
||
* 4.single_bit? #=> true
|
||
* 5.single_bit? #=> false
|
||
* 6.single_bit? #=> false
|
||
* 7.single_bit? #=> false
|
||
* 8.single_bit? #=> true
|
||
* 9.single_bit? #=> false
|
||
*
|
||
* 256.single_bit? #=> true
|
||
* 65536.single_bit? #=> true
|
||
*
|
||
*/
|
||
static VALUE
|
||
fix_single_bit_p(VALUE num)
|
||
{
|
||
long i = FIX2LONG(num);
|
||
if (i == 0)
|
||
return Qfalse;
|
||
if (i < 0)
|
||
i = -i;
|
||
return (i & (i-1)) == 0 ? Qtrue : Qfalse;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* int.next -> integer
|
||
* int.succ -> integer
|
||
*
|
||
... | ... | |
rb_define_method(rb_cFixnum, "odd?", fix_odd_p, 0);
|
||
rb_define_method(rb_cFixnum, "even?", fix_even_p, 0);
|
||
rb_define_method(rb_cFixnum, "succ", fix_succ, 0);
|
||
rb_define_method(rb_cFixnum, "single_bit?", fix_single_bit_p, 0);
|
||
rb_cFloat = rb_define_class("Float", rb_cNumeric);
|
||