single_bit_p.patch

Akira Tanaka, 08/05/2013 10:03 PM

Download (4.64 KB)

View differences:

bignum.c (working copy)
6555 6555
}
6556 6556

  
6557 6557
/*
6558
 *  call-seq:
6559
 *     big.single_bit?  ->  true or false
6560
 *
6561
 *  Returns true if abs(fixnum) has exactly a single one bit in binary format.
6562
 *  In other words, it returns true if the number is a power of two.
6563
 *
6564
 *     (-2**100-1).single_bit?  #=> false
6565
 *     (-2**100).single_bit?    #=> true
6566
 *     (-2**100+1).single_bit?  #=> false
6567
 *     (2**100-1).single_bit?   #=> false
6568
 *     (2**100).single_bit?     #=> true
6569
 *     (2**100+1).single_bit?   #=> false
6570
 *
6571
 */
6572
static VALUE
6573
rb_big_single_bit_p(VALUE num)
6574
{
6575
    long n;
6576
    BDIGIT *ds, d;
6577

  
6578
    ds = BDIGITS(num);
6579
    n = RBIGNUM_LEN(num);
6580

  
6581
    while (0 < n) {
6582
        --n;
6583
        d = ds[n];
6584
        if (d != 0) {
6585
            if (d & (d-1))
6586
                return Qfalse;
6587
            goto single_bit_word_found;
6588
        }
6589
    }
6590
    return Qfalse;
6591

  
6592
  single_bit_word_found:
6593
    while (0 < n) {
6594
        --n;
6595
        if (ds[n] != 0) {
6596
            return Qfalse;
6597
        }
6598
    }
6599
    return Qtrue;
6600
}
6601

  
6602
/*
6558 6603
 *  Bignum objects hold integers outside the range of
6559 6604
 *  Fixnum. Bignum objects are created
6560 6605
 *  automatically when integer calculations would otherwise overflow a
......
6615 6660
    rb_define_method(rb_cBignum, "size", rb_big_size, 0);
6616 6661
    rb_define_method(rb_cBignum, "odd?", rb_big_odd_p, 0);
6617 6662
    rb_define_method(rb_cBignum, "even?", rb_big_even_p, 0);
6663
    rb_define_method(rb_cBignum, "single_bit?", rb_big_single_bit_p, 0);
6618 6664

  
6619 6665
    power_cache_init();
6620 6666
}
test/ruby/test_integer.rb (working copy)
241 241
    end
242 242
    assert_equal(3 ^ 10, 3 ^ obj)
243 243
  end
244

  
245
  def test_single_bit?
246
    assert_equal(false,-5.single_bit?)
247
    assert_equal(true ,-4.single_bit?)
248
    assert_equal(false,-3.single_bit?)
249
    assert_equal(true ,-2.single_bit?)
250
    assert_equal(true ,-1.single_bit?)
251
    assert_equal(false, 0.single_bit?)
252
    assert_equal(true,  1.single_bit?)
253
    assert_equal(true,  2.single_bit?)
254
    assert_equal(false, 3.single_bit?)
255
    assert_equal(true,  4.single_bit?)
256
    assert_equal(false, 5.single_bit?)
257

  
258
    assert_equal(false, (3*2**128).single_bit?)
259

  
260
    2.upto(200) {|i|
261
      n = 2**i
262
      assert_equal(false, (n-1).single_bit?)
263
      assert_equal(true , n.single_bit?)
264
      assert_equal(false, (n+1).single_bit?)
265
      n = -n
266
      assert_equal(false, (n-1).single_bit?)
267
      assert_equal(true , n.single_bit?)
268
      assert_equal(false, (n+1).single_bit?)
269
    }
270
  end
244 271
end
numeric.c (working copy)
2410 2410

  
2411 2411
/*
2412 2412
 *  call-seq:
2413
 *     fixnum.single_bit?  ->  true or false
2414
 *
2415
 *  Returns true if abs(fixnum) has exactly a single one bit in binary format.
2416
 *  In other words, it returns true if the number is a power of two.
2417
 *  I.e. it returns true for 1, 2, 4, 8, ... and
2418
 *  -1, -2, -4, -8, ...
2419
 *
2420
 *     -9.single_bit?   #=> false
2421
 *     -8.single_bit?   #=> true
2422
 *     -7.single_bit?   #=> false
2423
 *     -6.single_bit?   #=> false
2424
 *     -5.single_bit?   #=> false
2425
 *     -4.single_bit?   #=> true
2426
 *     -3.single_bit?   #=> false
2427
 *     -2.single_bit?   #=> true
2428
 *     -1.single_bit?   #=> true
2429
 *     0.single_bit?    #=> false
2430
 *     1.single_bit?    #=> true
2431
 *     2.single_bit?    #=> true
2432
 *     3.single_bit?    #=> false
2433
 *     4.single_bit?    #=> true
2434
 *     5.single_bit?    #=> false
2435
 *     6.single_bit?    #=> false
2436
 *     7.single_bit?    #=> false
2437
 *     8.single_bit?    #=> true
2438
 *     9.single_bit?    #=> false
2439
 *
2440
 *     256.single_bit? #=> true
2441
 *     65536.single_bit? #=> true
2442
 *
2443
 */
2444
static VALUE
2445
fix_single_bit_p(VALUE num)
2446
{
2447
    long i = FIX2LONG(num);
2448

  
2449
    if (i == 0)
2450
        return Qfalse;
2451

  
2452
    if (i < 0)
2453
        i = -i;
2454

  
2455
    return (i & (i-1)) == 0 ? Qtrue : Qfalse;
2456
}
2457

  
2458

  
2459
/*
2460
 *  call-seq:
2413 2461
 *     int.next  ->  integer
2414 2462
 *     int.succ  ->  integer
2415 2463
 *
......
3868 3916
    rb_define_method(rb_cFixnum, "odd?", fix_odd_p, 0);
3869 3917
    rb_define_method(rb_cFixnum, "even?", fix_even_p, 0);
3870 3918
    rb_define_method(rb_cFixnum, "succ", fix_succ, 0);
3919
    rb_define_method(rb_cFixnum, "single_bit?", fix_single_bit_p, 0);
3871 3920

  
3872 3921
    rb_cFloat  = rb_define_class("Float", rb_cNumeric);
3873 3922