bnghtz

convert_num_system.pl

Feb 3rd, 2014
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 3.58 KB | None | 0 0
  1. #! /usr/bin/perl
  2.  
  3. ###############################################################################
  4. # convert between numeric systems                                     BnGhTz  #
  5. #                                                                             #
  6. # Usage: convert_num_system.pl number from [to]                               #
  7. #  number: number to convert                                                  #
  8. #  from:   base radix (int 2 - 36)                                            #
  9. #  to:     target radix (int 2 - 36); The default is 10.                      #
  10. #                                                                             #
  11. # Examples:                                                                   #
  12. # ./convert_num_system.pl foo 25                                              #
  13. # 9999                                                                        #
  14. #                                                                             #
  15. # ./convert_num_system.pl 301 36 7                                            #
  16. # 14224                                                                       #
  17. #                                                                             #
  18. ###############################################################################
  19.  
  20. ###### INCLUDES ###############################################################
  21. use strict;
  22. use warnings;
  23.  
  24. ###### VARS ###################################################################
  25. my $ver = 'v.0.0.1';
  26. my $name = (split(/\/|\\/, $0))[-1];
  27. my $max_radix = 36;
  28. my $min_radix = 2;
  29.  
  30. ###### SUBS ###################################################################
  31. sub usage(;$)
  32. {
  33.   my $txt = (defined $_[0]) ? '' : $_[0];
  34.   die "Usage: $name number from [to]\n\n" .
  35.       "  number: number to convert\n" .
  36.       "  from:   base radix (int $min_radix - $max_radix)\n" .
  37.       "  to:     target radix (int $min_radix - $max_radix); The default is 10.\n\n";
  38. }
  39.  
  40. sub check_radix($)
  41. {
  42.   my $x = shift;
  43.  
  44.   return undef if $x =~ /\D/;
  45.   return 1 if (($x !~ /\D/) && ($x >= $min_radix) && ($x <= $max_radix));
  46. }
  47.  
  48. sub dec_to_chr($)
  49. {
  50.   return $_[0] > 9 ? chr($_[0] + ord('A') - 10) : $_[0];
  51. }
  52.  
  53. sub chr_to_dec($)
  54. {
  55.   my $x = uc($_[0]);
  56.   return ($_[0] =~ m/^\D$/) ? ord($x) - ord('A') + 10 : $_[0];
  57. }
  58.  
  59. sub search_min($)
  60. {
  61.   my $ret = 0;
  62.  
  63.   while ($_[0] =~ m/(.)/g)
  64.   {
  65.     my $x = chr_to_dec($1) + 1;
  66.     $ret = $x if $x > $ret;
  67.   }
  68.  
  69.   return $ret;
  70. }
  71.  
  72. sub scale_to_dec($$)
  73. {
  74.   return scale_to_any(@_, 10);
  75. }
  76.  
  77. sub scale_to_any($$$)
  78. {
  79.   my ($num, $from, $to) = @_;
  80.  
  81.   return 0 if $num eq '0';
  82.  
  83.   my $min = search_min($num);
  84.   die "Invalid radix '$from'. Minimal radix is '$min'\n" if ($min > $from);
  85.  
  86.   my @nums = $num =~ m/(.)/g;
  87.   my $ret = '';
  88.  
  89.   # to 10;
  90.   my $_10 = 0;
  91.   for (my $i = 0; $i <= $#nums; $i++)
  92.   {
  93.     $_10 += chr_to_dec($nums[$#nums - $i]) * $from ** $i;
  94.   }
  95.  
  96.   # to oth;
  97.   if ($to == 10 && 0)
  98.   {
  99.     $ret = $_10;
  100.   }
  101.   else
  102.   {
  103.     while ($_10)
  104.     {
  105.       my $c = $_10 % $to;
  106.       $_10 = ($_10 - $c) / $to;
  107.       $c = dec_to_chr($c) if $c > 9;
  108.       $ret =  $c . $ret;
  109.     }
  110.   }
  111.  
  112.   return $ret;
  113. }
  114.  
  115. ###### PROGRAM ################################################################
  116.  
  117. # inputs
  118. my ($number, $from, $to) = @ARGV;
  119.  
  120. usage() if (
  121.   (!defined($from) || !check_radix($from)) ||
  122.   (defined($to) && !check_radix($to))
  123. );
  124.  
  125. if ($number =~ /^-/)
  126. {
  127.   $number =~ s/^-//;
  128.   warn "cannot handle negative number\nretest with: $number\n\n";
  129. }
  130.  
  131. $to ||= 10;
  132.  
  133. my $out = scale_to_any($number, $from, $to);
  134. print "$out\n" if defined($out);
Advertisement
Add Comment
Please, Sign In to add comment