summaryrefslogtreecommitdiff
path: root/dist/Math-BigInt
diff options
context:
space:
mode:
authorPeter John Acklam <pjacklam@online.no>2010-11-04 18:08:56 +0100
committerFlorian Ragwitz <rafl@debian.org>2010-11-07 16:15:22 +0100
commit84f8f1aed5c8e9f51bb9d93e9040c787cb1c311c (patch)
treeadc1b5f8eee922f6d260765b77cc4d7d7874930a /dist/Math-BigInt
parent9681bfa67d7baa813bc256afd3d3c6380121f85d (diff)
downloadperl-84f8f1aed5c8e9f51bb9d93e9040c787cb1c311c.tar.gz
RT ticket #61812: digit($n) with $n "out of range"
The _digit($n) method in Math::BigInt::Calc should return 0 when $n refers to a leading zero digit. E.g., the number '314' is just the same as '000314', except that the leading zeros omitted, so _digit($n) should return '0' when $n refers to a leading zero digit. - lib/Math/BigInt/Calc.pm: Improve comments in source code. Add code returning zero when input refers to a leading zero digit. Removed redundant zero padding in temporary string argument to substr(). - t/bigintc.t: Add four test cases verifying the behaviour. Increment number of test by four.
Diffstat (limited to 'dist/Math-BigInt')
-rw-r--r--dist/Math-BigInt/lib/Math/BigInt/Calc.pm18
-rw-r--r--dist/Math-BigInt/t/bigintc.t6
2 files changed, 13 insertions, 11 deletions
diff --git a/dist/Math-BigInt/lib/Math/BigInt/Calc.pm b/dist/Math-BigInt/lib/Math/BigInt/Calc.pm
index f5f4ff1350..af638f26f8 100644
--- a/dist/Math-BigInt/lib/Math/BigInt/Calc.pm
+++ b/dist/Math-BigInt/lib/Math/BigInt/Calc.pm
@@ -1206,20 +1206,18 @@ sub _len
sub _digit
{
- # return the nth digit, negative values count backward
- # zero is rightmost, so _digit(123,0) will give 3
+ # Return the nth digit. Zero is rightmost, so _digit(123,0) gives 3.
+ # Negative values count from the left, so _digit(123, -1) gives 1.
my ($c,$x,$n) = @_;
my $len = _len('',$x);
- $n = $len+$n if $n < 0; # -1 last, -2 second-to-last
- $n = abs($n); # if negative was too big
- $len--; $n = $len if $n > $len; # n to big?
-
- my $elem = int($n / $BASE_LEN); # which array element
- my $digit = $n % $BASE_LEN; # which digit in this element
- $elem = '0' x $BASE_LEN . @$x[$elem]; # get element padded with 0's
- substr($elem,-$digit-1,1);
+ $n += $len if $n < 0; # -1 last, -2 second-to-last
+ return "0" if $n < 0 || $n >= $len; # return 0 for digits out of range
+
+ my $elem = int($n / $BASE_LEN); # which array element
+ my $digit = $n % $BASE_LEN; # which digit in this element
+ substr("$x->[$elem]", -$digit-1, 1);
}
sub _zeros
diff --git a/dist/Math-BigInt/t/bigintc.t b/dist/Math-BigInt/t/bigintc.t
index 9b94aeb561..3123ff8668 100644
--- a/dist/Math-BigInt/t/bigintc.t
+++ b/dist/Math-BigInt/t/bigintc.t
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
use strict;
-use Test::More tests => 375;
+use Test::More tests => 379;
use Math::BigInt::Calc;
@@ -129,9 +129,13 @@ $x = $C->_new("123456789");
is ($C->_digit($x,0),9);
is ($C->_digit($x,1),8);
is ($C->_digit($x,2),7);
+is ($C->_digit($x,8),1);
+is ($C->_digit($x,9),0);
is ($C->_digit($x,-1),1);
is ($C->_digit($x,-2),2);
is ($C->_digit($x,-3),3);
+is ($C->_digit($x,-9),9);
+is ($C->_digit($x,-10),0);
# _copy
foreach (qw/ 1 12 123 1234 12345 123456 1234567 12345678 123456789/)