@@ -4475,6 +4475,111 @@ rb_int_bit_length(VALUE num)
4475
4475
return Qnil ;
4476
4476
}
4477
4477
4478
+ /*
4479
+ * Document-method: Integer#digits(base=10)
4480
+ * call-seq:
4481
+ * int.digits -> [int]
4482
+ * int.digits(base) -> [int]
4483
+ *
4484
+ * Returns the array including the digits extracted by place-value notation
4485
+ * with radix +base+ of +int+.
4486
+ *
4487
+ * +base+ should be greater than or equal to 2.
4488
+ *
4489
+ * 12345.digits #=> [5, 4, 3, 2, 1]
4490
+ * 12345.digits(7) #=> [4, 6, 6, 0, 5]
4491
+ * -12345.digits(7) #=> [4, 6, 6, 0, 5]
4492
+ * 12345.digits(100) #=> [45, 23, 1]
4493
+ *
4494
+ */
4495
+
4496
+ static VALUE
4497
+ rb_fix_digits (VALUE fix , long base )
4498
+ {
4499
+ VALUE digits ;
4500
+ long x = FIX2LONG (fix );
4501
+
4502
+ if (base < 2 )
4503
+ rb_raise (rb_eArgError , "invalid radix %ld" , base );
4504
+
4505
+ if (x == 0 ) {
4506
+ return rb_ary_new_from_args (1 , INT2FIX (0 ));
4507
+ }
4508
+ else if (x < 0 )
4509
+ x = - x ;
4510
+
4511
+ digits = rb_ary_new ();
4512
+ while (x > 0 ) {
4513
+ long q = x % base ;
4514
+ rb_ary_push (digits , LONG2NUM (q ));
4515
+ x /= base ;
4516
+ }
4517
+
4518
+ return digits ;
4519
+ }
4520
+
4521
+ static VALUE
4522
+ rb_int_digits_bigbase (VALUE num , VALUE base )
4523
+ {
4524
+ VALUE digits ;
4525
+
4526
+ if (RB_TYPE_P (base , T_BIGNUM )) {
4527
+ base = rb_big_norm (base );
4528
+ }
4529
+
4530
+ if (FIXNUM_P (base ) && FIX2LONG (base ) < 2 )
4531
+ rb_raise (rb_eArgError , "invalid radix %ld" , FIX2LONG (base ));
4532
+ else if (RB_TYPE_P (base , T_BIGNUM ) && BIGNUM_NEGATIVE_P (base ))
4533
+ rb_raise (rb_eArgError , "negative radix" );
4534
+
4535
+ if (FIXNUM_P (base ) && FIXNUM_P (num ))
4536
+ return rb_fix_digits (num , FIX2LONG (base ));
4537
+
4538
+ if (FIXNUM_P (num )) {
4539
+ long x = FIX2LONG (num );
4540
+ if (x < 0 ) x = - x ;
4541
+ return rb_ary_new_from_args (1 , LONG2FIX (x ));
4542
+ }
4543
+
4544
+ digits = rb_ary_new ();
4545
+ while (!FIXNUM_P (num ) || FIX2LONG (num ) > 0 ) {
4546
+ VALUE rq = int_divmod (num , base );
4547
+
4548
+ rb_ary_push (digits , RARRAY_AREF (rq , 1 ));
4549
+
4550
+ num = RARRAY_AREF (rq , 0 );
4551
+ }
4552
+
4553
+ return digits ;
4554
+ }
4555
+
4556
+ static VALUE
4557
+ rb_int_digits (int argc , VALUE * argv , VALUE num )
4558
+ {
4559
+ long base ;
4560
+
4561
+ if (rb_check_arity (argc , 0 , 1 )) {
4562
+ if (!RB_INTEGER_TYPE_P (argv [0 ]))
4563
+ rb_raise (rb_eTypeError , "wrong argument type %s (expected Integer)" ,
4564
+ rb_obj_classname (argv [0 ]));
4565
+ if (RB_TYPE_P (argv [0 ], T_BIGNUM ))
4566
+ return rb_int_digits_bigbase (num , argv [0 ]);
4567
+
4568
+ base = FIX2LONG (argv [0 ]);
4569
+ if (base < 2 )
4570
+ rb_raise (rb_eArgError , "invalid radix %ld" , base );
4571
+ }
4572
+ else
4573
+ base = 10 ;
4574
+
4575
+ if (FIXNUM_P (num ))
4576
+ return rb_fix_digits (num , base );
4577
+ else if (RB_TYPE_P (num , T_BIGNUM ))
4578
+ return rb_int_digits_bigbase (num , LONG2FIX (base ));
4579
+
4580
+ return Qnil ;
4581
+ }
4582
+
4478
4583
/*
4479
4584
* Document-method: Integer#upto
4480
4585
* call-seq:
@@ -4956,6 +5061,7 @@ Init_Numeric(void)
4956
5061
4957
5062
rb_define_method (rb_cInteger , "size" , int_size , 0 );
4958
5063
rb_define_method (rb_cInteger , "bit_length" , rb_int_bit_length , 0 );
5064
+ rb_define_method (rb_cInteger , "digits" , rb_int_digits , -1 );
4959
5065
4960
5066
rb_cFixnum = rb_cInteger ;
4961
5067
rb_define_const (rb_cObject , "Fixnum" , rb_cInteger );
0 commit comments