Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /usr/bin/perl
- ###############################################################################
- # convert between numeric systems BnGhTz #
- # #
- # Usage: convert_num_system.pl number from [to] #
- # number: number to convert #
- # from: base radix (int 2 - 36) #
- # to: target radix (int 2 - 36); The default is 10. #
- # #
- # Examples: #
- # ./convert_num_system.pl foo 25 #
- # 9999 #
- # #
- # ./convert_num_system.pl 301 36 7 #
- # 14224 #
- # #
- ###############################################################################
- ###### INCLUDES ###############################################################
- use strict;
- use warnings;
- ###### VARS ###################################################################
- my $ver = 'v.0.0.1';
- my $name = (split(/\/|\\/, $0))[-1];
- my $max_radix = 36;
- my $min_radix = 2;
- ###### SUBS ###################################################################
- sub usage(;$)
- {
- my $txt = (defined $_[0]) ? '' : $_[0];
- die "Usage: $name number from [to]\n\n" .
- " number: number to convert\n" .
- " from: base radix (int $min_radix - $max_radix)\n" .
- " to: target radix (int $min_radix - $max_radix); The default is 10.\n\n";
- }
- sub check_radix($)
- {
- my $x = shift;
- return undef if $x =~ /\D/;
- return 1 if (($x !~ /\D/) && ($x >= $min_radix) && ($x <= $max_radix));
- }
- sub dec_to_chr($)
- {
- return $_[0] > 9 ? chr($_[0] + ord('A') - 10) : $_[0];
- }
- sub chr_to_dec($)
- {
- my $x = uc($_[0]);
- return ($_[0] =~ m/^\D$/) ? ord($x) - ord('A') + 10 : $_[0];
- }
- sub search_min($)
- {
- my $ret = 0;
- while ($_[0] =~ m/(.)/g)
- {
- my $x = chr_to_dec($1) + 1;
- $ret = $x if $x > $ret;
- }
- return $ret;
- }
- sub scale_to_dec($$)
- {
- return scale_to_any(@_, 10);
- }
- sub scale_to_any($$$)
- {
- my ($num, $from, $to) = @_;
- return 0 if $num eq '0';
- my $min = search_min($num);
- die "Invalid radix '$from'. Minimal radix is '$min'\n" if ($min > $from);
- my @nums = $num =~ m/(.)/g;
- my $ret = '';
- # to 10;
- my $_10 = 0;
- for (my $i = 0; $i <= $#nums; $i++)
- {
- $_10 += chr_to_dec($nums[$#nums - $i]) * $from ** $i;
- }
- # to oth;
- if ($to == 10 && 0)
- {
- $ret = $_10;
- }
- else
- {
- while ($_10)
- {
- my $c = $_10 % $to;
- $_10 = ($_10 - $c) / $to;
- $c = dec_to_chr($c) if $c > 9;
- $ret = $c . $ret;
- }
- }
- return $ret;
- }
- ###### PROGRAM ################################################################
- # inputs
- my ($number, $from, $to) = @ARGV;
- usage() if (
- (!defined($from) || !check_radix($from)) ||
- (defined($to) && !check_radix($to))
- );
- if ($number =~ /^-/)
- {
- $number =~ s/^-//;
- warn "cannot handle negative number\nretest with: $number\n\n";
- }
- $to ||= 10;
- my $out = scale_to_any($number, $from, $to);
- print "$out\n" if defined($out);
Advertisement
Add Comment
Please, Sign In to add comment