summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--numeric.c42
-rw-r--r--test/ruby/test_integer_comb.rb24
3 files changed, 67 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 3b1e42fc75..41cdbd95c6 100644
--- a/NEWS
+++ b/NEWS
@@ -82,6 +82,7 @@ with all sufficient information, see the ChangeLog file or Redmine
[Bug #13420]
* Integer#pow now has an optional modulo argument for calculating modular
exponentiation. [Feature #12508] [Feature #11003]
+ * Integer#allbits?, Integer#anybits?, Integer#nobits? [Feature #12753]
* Kernel
diff --git a/numeric.c b/numeric.c
index dcf766e1c3..cd84956632 100644
--- a/numeric.c
+++ b/numeric.c
@@ -3166,6 +3166,45 @@ int_even_p(VALUE num)
}
/*
+ * call-seq:
+ * int.allbits?(mask) -> true or false
+ *
+ * Returns +true+ if all bits of <code>+int+ & +mask+</code> is 1.
+ */
+
+static VALUE
+int_allbits_p(VALUE num, VALUE mask)
+{
+ return rb_int_equal(rb_int_and(num, mask), mask);
+}
+
+/*
+ * call-seq:
+ * int.anybits?(mask) -> true or false
+ *
+ * Returns +true+ if any bits of <code>+int+ & +mask+</code> is 1.
+ */
+
+static VALUE
+int_anybits_p(VALUE num, VALUE mask)
+{
+ return num_zero_p(rb_int_and(num, mask)) ? Qfalse : Qtrue;
+}
+
+/*
+ * call-seq:
+ * int.nobits?(mask) -> true or false
+ *
+ * Returns +true+ if no bits of <code>+int+ & +mask+</code> is 1.
+ */
+
+static VALUE
+int_nobits_p(VALUE num, VALUE mask)
+{
+ return num_zero_p(rb_int_and(num, mask));
+}
+
+/*
* Document-method: Integer#succ
* Document-method: Integer#next
* call-seq:
@@ -5352,6 +5391,9 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "integer?", int_int_p, 0);
rb_define_method(rb_cInteger, "odd?", rb_int_odd_p, 0);
rb_define_method(rb_cInteger, "even?", int_even_p, 0);
+ rb_define_method(rb_cInteger, "allbits?", int_allbits_p, 1);
+ rb_define_method(rb_cInteger, "anybits?", int_anybits_p, 1);
+ rb_define_method(rb_cInteger, "nobits?", int_nobits_p, 1);
rb_define_method(rb_cInteger, "upto", int_upto, 1);
rb_define_method(rb_cInteger, "downto", int_downto, 1);
rb_define_method(rb_cInteger, "times", int_dotimes, 0);
diff --git a/test/ruby/test_integer_comb.rb b/test/ruby/test_integer_comb.rb
index 80d08cac04..1ad13dd31b 100644
--- a/test/ruby/test_integer_comb.rb
+++ b/test/ruby/test_integer_comb.rb
@@ -457,6 +457,30 @@ class TestIntegerComb < Test::Unit::TestCase
}
end
+ def test_allbits_p
+ VS.each {|a|
+ VS.each {|b|
+ assert_equal((a & b) == b, a.allbits?(b), "(#{a}).allbits?(#{b}")
+ }
+ }
+ end
+
+ def test_anybits_p
+ VS.each {|a|
+ VS.each {|b|
+ assert_equal((a & b) != 0, a.anybits?(b), "(#{a}).anybits?(#{b}")
+ }
+ }
+ end
+
+ def test_nobits_p
+ VS.each {|a|
+ VS.each {|b|
+ assert_equal((a & b) == 0, a.nobits?(b), "(#{a}).nobits?(#{b}")
+ }
+ }
+ end
+
def test_to_s
2.upto(36) {|radix|
VS.each {|a|