[Perl] 如何將數字換底
作者:gugod 發佈於: #perlPerl 的數值,在其內部十進位來表示。若要將十進位數字轉成其他進位數字,可用以下的 to_base($base, $n)
函式。其處理對象 $n
是十位數字數值的純量變數。其傳回值也是一個純量變數。
use v5.40;
sub to_base ($base, $n) {
state @digits = ('0'..'9', 'A'..'Z');
die 'base argument is out of rage. Is: $base, should be 2..36'
unless 2 <= $base <= 36;
# Recursive calls on an inner-sub to avoid doing redundant
# param-validations.
return sub ($base, $n) {
my $lsd = $digits[ $n % $base ];
my $high = int($n / $base);
return ($high > 0 ? __SUB__->($high, $base) : "") . $lsd;
}->($n, $base);
}
而要將某個底數不是 10 的數字轉換成十進位的方式,可用以下的 from_base($base, $n)
函式。
use v5.40;
sub from_base ($base, $n) {
state @digits = ('0'..'9', 'A'..'Z');
state %decOf = map { $digits[$_] => $_ } (0..$#digits);
die 'base argument is out of rage. Is: $base, should be 2..36'
unless 2 <= $base <= 36;
# Recursive calls on an inner-sub to avoid doing redundant
# param-validations.
return sub ($base, $n) {
return 0 if $n eq "";
my $lsd = substr($n, -1);
my $high = substr($n, 0, -1);
return $base * __SUB__->($base, $high) + $decOf{$lsd};
}->($base, $n);
}
這兩個函式都是以遞迴演算法寫成的。同時,為了避免多次地對不會變動的 $base
做格式上的檢查,實際上遞迴的函式並非它們本體,而是其內部一個較小的無名函式。在 Perl 中可以使用 __SUB__
來表示「目前這個函式」,所以無名函式也可以遞迴呼叫自己。