Conversor de decimal a otra base menor a 36 y viceversa
El programa toma un número de argv[1] y una base de argv[2] y lo convierte al
número base [0..9,A-Z], devolviéndolo a decimal como forma de comprobación (ver
el link anterior to-bin). Existen bases problemáticas, que agotarían la memoria
antes de dar por redondeado a 0 la parte decimal; en estos casos, el programa
limita a 1000 el número de caracteres de la parte decimal, sin que se altere la
conversión al número original.
#!/usr/local/bin/perl -w
if ($ARGV[0] =~ /[h,H]/ || @ARGV<2){ die "Usage: $0 < number > < base > (base<=36)"; }
$n = $ARGV[0];
if ($n+0 ne $n) { die "Not a number"; }
$base = $ARGV[1];
if ($base+0 ne $base) { die "Not a number"; }
$base=int($base);
$base= $base % 37;
if ($base<2) { $base=2; }
if ($n<0) { $n = abs ($n); $flag="-"; }else {$flag = ""; }
$i = int($n);
$j = $n-$i;
for (;;){
push @ii, c($i % $base);
$i = int($i/$base);
if ($i<=$base-1){ push @ii, c($i); last; }
}
@ii=reverse(@ii);
for (;;){
$j *=$base;
push @jj, c(int($j));
$j -= int($j);
$count++;
if ($j==0 || $count==1000) { last; }
}
$str= $flag."@ii"."."."@jj";
$str =~ s/ //g;
print "$str\n";
$str =~ s/([\w]+)\.([\w]+)/$1\.$2/;
$a=$1; $b=$2;
for $i (0..length($a)-1){
$num += ($base**$i)*cc(substr($a,-1,1,""));
}
for $j (1..length($b)){
$num += ($base**(-$j))*cc(substr($b,0,1,""));
}
if ($flag eq "-") { $num *=-1; }
print "$num\n";
sub c{
my $c = shift;
if ($c<10){ return "$c"; }
else { return chr(64+$c-9); }
}
sub cc{
my $c = shift;
if ($c =~ /\d/){ return $c; }
else { return ord($c)-64+9; }
}
__END__