# base($number, $inbase, $outbase) transforms a number from one # base to another. # # Examples: # base(17, 9, 2) converts 17 (base 9) to base 2: 10000. # base("fff", 16, 3) converts fff (base 16) to base 3: 12121200. # base("g", 17, 10) converts g (base 17) to base 10: 16. # # Uses the logbase() function defined below. # # Returns undef on error. # sub base { my ($number, $inbase, $outbase) = @_; my ($realnum, $output, $i, $digit); # Convert the number (which might have letters) to lowercase. $number = lc($number); # Return undef (or an empty list) if the base is too weird. return if $inbase > 36 or $outbase > 36 or $inbase < 2 or $outbase < 2; # Convert $number from base $inbase to base 10. for $digit (reverse split(//, $number)) { $digit = ord($digit) - 87 if ord($digit) > 96; return if $digit >= $inbase; $realnum += $digit * ($inbase ** $i++); } # Convert the number from base 10 to $outbase. # logbase() is defined below. for ($i = int(logbase($realnum, $outbase)); $i >= 0; $i--) { $digit = int($realnum / ($outbase ** $i)); $realnum -= $digit * ($outbase ** $i); $digit = ord($digit + 49) if ord($digit) > 57; $output .= $digit; } return $output; } # base(17, 9, 2) converts 17 (base 9) to base 2: 10000. print base(17, 9, 2), "\n"; # base("fff", 16, 3) converts fff (base 16) to base 3: 12121200. print base("fff", 16, 3), "\n"; # base("g", 17, 10) converts g (base 17) to base 10: 16. print base("g", 17, 10), "\n"; # logbase($number, $base) computes the logarithm of number in base $base. # # Example: logbase(243, 3) is 5, because 3 ** 5 is 243. # sub logbase { my ($number, $base) = @_; return if $number <= 0 or $base <= 0 or $base == 1; return log($number) / log($base); }