to any base <=36 and back


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__


Back