bit_length.patch

Akira Tanaka, 08/05/2013 09:48 PM

Download (4.59 KB)

View differences:

bignum.c (working copy)
6439 6439

  
6440 6440
/*
6441 6441
 *  call-seq:
6442
 *     big.bit_length -> integer
6443
 *
6444
 *  Returns the number of bits of the absolute value of <i>big</i>.
6445
 *
6446
 *     (-2**10000-1).bit_length  #=> 10001
6447
 *     (-2**10000).bit_length    #=> 10001
6448
 *     (-2**10000+1).bit_length  #=> 10000
6449
 *
6450
 *     (-2**1000-1).bit_length   #=> 1001
6451
 *     (-2**1000).bit_length     #=> 1001
6452
 *     (-2**1000+1).bit_length   #=> 1000
6453
 *
6454
 *     (2**1000-1).bit_length    #=> 1000
6455
 *     (2**1000).bit_length      #=> 1001
6456
 *     (2**1000+1).bit_length    #=> 1001
6457
 *
6458
 *     (2**10000-1).bit_length   #=> 10000
6459
 *     (2**10000).bit_length     #=> 10001
6460
 *     (2**10000+1).bit_length   #=> 10001
6461
 *
6462
 */
6463

  
6464
static VALUE
6465
rb_big_bit_length(VALUE big)
6466
{
6467
    int nlz_bits;
6468
    size_t numbytes;
6469

  
6470
    static const BDIGIT char_bit[1] = { CHAR_BIT };
6471
    BDIGIT numbytes_bary[bdigit_roomof(sizeof(size_t))];
6472
    BDIGIT nlz_bary[1];
6473
    BDIGIT result_bary[bdigit_roomof(sizeof(size_t)+1)];
6474

  
6475
    numbytes = rb_absint_size(big, &nlz_bits);
6476

  
6477
    if (numbytes <= SIZE_MAX / CHAR_BIT) {
6478
        return SIZET2NUM(numbytes * CHAR_BIT - nlz_bits);
6479
    }
6480

  
6481
    nlz_bary[0] = nlz_bits;
6482

  
6483
    bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1, sizeof(numbytes), 0,
6484
            INTEGER_PACK_NATIVE_BYTE_ORDER);
6485
    BARY_MUL1(result_bary, numbytes_bary, char_bit);
6486
    BARY_SUB(result_bary, result_bary, nlz_bary);
6487

  
6488
    return rb_integer_unpack(result_bary, numberof(result_bary), sizeof(BDIGIT), 0,
6489
            INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
6490
}
6491

  
6492
/*
6493
 *  call-seq:
6494
 *     fix.bit_length -> integer
6495
 *
6496
 *  Returns the number of bits of the absolute value of <i>fix</i>.
6497
 *
6498
 *     (-2**12-1).bit_length)    #=> 13
6499
 *     (-2**12).bit_length)      #=> 13
6500
 *     (-2**12+1).bit_length)    #=> 12
6501
 *     -0x100.bit_length         #=> 9
6502
 *     -0xff.bit_length          #=> 8
6503
 *     -1.bit_length             #=> 1
6504
 *     0.bit_length              #=> 0
6505
 *     1.bit_length              #=> 1
6506
 *     0xff.bit_length           #=> 8
6507
 *     0x100.bit_length          #=> 9
6508
 *     (2**12-1).bit_length      #=> 12
6509
 *     (2**12).bit_length        #=> 13
6510
 *     (2**12+1).bit_length      #=> 13
6511
 */
6512

  
6513
static VALUE
6514
rb_fix_bit_length(VALUE fix)
6515
{
6516
    long v = FIX2LONG(fix);
6517
    if (v < 0)
6518
        v = -v;
6519
    return LONG2FIX(bitsize(v));
6520
}
6521

  
6522
/*
6523
 *  call-seq:
6442 6524
 *     big.odd? -> true or false
6443 6525
 *
6444 6526
 *  Returns <code>true</code> if <i>big</i> is an odd number.
......
6528 6610
    rb_define_method(rb_cBignum, "abs", rb_big_abs, 0);
6529 6611
    rb_define_method(rb_cBignum, "magnitude", rb_big_abs, 0);
6530 6612
    rb_define_method(rb_cBignum, "size", rb_big_size, 0);
6613
    rb_define_method(rb_cBignum, "bit_length", rb_big_bit_length, 0);
6531 6614
    rb_define_method(rb_cBignum, "odd?", rb_big_odd_p, 0);
6532 6615
    rb_define_method(rb_cBignum, "even?", rb_big_even_p, 0);
6533 6616

  
6617
    rb_define_method(rb_cFixnum, "bit_length", rb_fix_bit_length, 0);
6618

  
6534 6619
    power_cache_init();
6535 6620
}
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_bit_length
246
    assert_equal(13, (-2**12-1).bit_length)
247
    assert_equal(13, (-2**12).bit_length)
248
    assert_equal(12, (-2**12+1).bit_length)
249
    assert_equal(9, -0x100.bit_length)
250
    assert_equal(8, -0xff.bit_length)
251
    assert_equal(1, -1.bit_length)
252
    assert_equal(0, 0.bit_length)
253
    assert_equal(1, 1.bit_length)
254
    assert_equal(8, 0xff.bit_length)
255
    assert_equal(9, 0x100.bit_length)
256
    assert_equal(12, (2**12-1).bit_length)
257
    assert_equal(13, (2**12).bit_length)
258
    assert_equal(13, (2**12+1).bit_length)
259

  
260
    assert_equal(10001, (-2**10000-1).bit_length)
261
    assert_equal(10001, (-2**10000).bit_length)
262
    assert_equal(10000, (-2**10000+1).bit_length)
263
    assert_equal(10000, (2**10000-1).bit_length)
264
    assert_equal(10001, (2**10000).bit_length)
265
    assert_equal(10001, (2**10000+1).bit_length)
266

  
267
    1.upto(1000) {|i|
268
      n = 2**i
269
      assert_equal(i+1, (-n-1).bit_length)
270
      assert_equal(i+1, (-n).bit_length)
271
      assert_equal(i,   (-n+1).bit_length)
272
      assert_equal(i,   (n-1).bit_length)
273
      assert_equal(i+1, (n).bit_length)
274
      assert_equal(i+1, (n+1).bit_length)
275
    }
276
  end
244 277
end