Перевод числа из 10-тичной системы счисления в другую и обратно

Вопросы и обсуждения, касающиеся программирования на Perl.
Ответить
Аватара пользователя
ZEN
Администратор
Сообщения: 1357
Зарегистрирован: 27 сен 2012, 18:23
Темы: 208
Откуда: Украина, Одесса
Статус: Не в сети

Перевод числа из 10-тичной системы счисления в другую и обратно

Сообщение ZEN » 23 июл 2013, 19:35

[spoiler="Подробное описание задания"]Входные данные: три числа.
Первое тип операции (1 - переводим из 10-ой, 2 - переводим в 10-ую).
Второе - число, которое надо переводить.
Третье - основание системы.

Выходные данные: одно преобразованное число

Программа должна корректно обрабатывать неправильный ввод (например задана двоичная система и число 12).
Программа должна работать с 36 системами, для систем счисления больше 10 программа должна брать буквы латинского алфавита (10 чисел + 26 букв).

Содержимое тестового файле tests.dat:
1,14,16
1,4,16

1,444,16
1,14,2
1,444,2
1,14,5
1,444,5
1,14,26
1,4,26
1,444,26
2,1110,2
2,111011,2
2,4,16
2,1BC,16
2,11,2
2,4,26
2,E,26
2,H2,26
2,24,5
2,4,5
2,3234,5
2,5BB,13
Запускаем скрипт:
./script_01.pl tests.dat > results.log 2> errors_description.log


Результат в файле results.log:
E
4
Error
1BC
1110
110111100
24
3234
E
4
H2
14
59
4
444
3
4
14
444
14
4
444
999[/spoiler]

Код: Выделить всё

#!/usr/bin/perl -w
use strict;
use Switch;

my @symbols = ('0','1','2','3','4','5','6','7','8','9',
                 'A','B','C','D','E','F','G','H','I','J','K','L','M',
                 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z');

sub index_of_array {
    if (!defined $_[0]) {
        print STDERR "Error! index_of_array require a parameter";
        return -2;
    }
    
    for (my $i=0; $i < $#symbols + 1; $i++) {
        if ( $_[0] eq $symbols[$i] ) {
            return $i;
        }
    }
    return -1;
}

sub number_base_check {
    my $res = 1;
    if (defined $_[0] && defined $_[1]) {
        my $number = $_[0];
        my $base = $_[1];
        my $tmp = 0;
        
        my $len = length($number) - 1; 
        for ( my $i = 0; $i <= $len; $i++ ) {
            my $num = index_of_array(substr( $number, $i, 1 ));
            if ( $num >= $base || $num < 0) {
                $res = undef;
                last;
            }
        }
        return $res;
    } else {
        print STDOUT "Error\n";
        print STDERR "Error! Not enough values in number_base_check function\n";
        return undef;
    }
}

sub dec2any {
    if (defined $_[0] && defined $_[1]) {
        my $number = $_[0];
        my $base = $_[1];
        my $tmp;
        
        if ($number < $base) {
            $tmp = $symbols[$number];
            return $tmp;
        }
        
        $tmp .= dec2any( ($number / $base), $base );
        return $tmp .= $symbols[$number % $base];
    } else {
        print STDOUT "Error\n";
        print STDERR "Error! Not enough values in dec2any function\n";
    }
}

sub any2dec {
    if (defined $_[0] && defined $_[1]) {
        my $number = $_[0];
        my $base = $_[1];
        my $tmp = 0;
        
        my $len = length($number) - 1; 
        for ( my $i = 0; $i <= $len; $i++ ) {
            my $num = index_of_array(substr( $number, $i, 1 ));
            $tmp = $tmp + $num * ($base**($len-$i));
        }
        return $tmp;
    } else {
        print STDOUT "Error\n";
        print STDERR "Error! Not enough values in any2dec function\n";
    }     
}

my $test_file_path = $ARGV[0];
open( FH, "<", "$test_file_path") or die "Can not open test file: $!";

while ( my $str = <FH> ) {
    # < обработка >
    $str =~ s/\s*,\s*/,/g;
    $str =~ s/^\s*//g;
    $str =~ s/\s*$//g;
    $str = uc($str);
    
    my ($a, $b, $c) = split(",", $str);
    if (defined $a && defined $b && defined $c &&
    $a ne "" && $b ne "" && $c ne "") {
        switch ($a) {
            case 1 {
                if ( number_base_check($b, 10) ) {
                    my $number = dec2any($b, $c);
                    print STDOUT "$number\n";
                } else {
                    print STDOUT "Error\n";  
                    print STDERR "Check number notation\n"; 
                }
            }
            case 2 {
                if ( number_base_check($b, $c) ) {
                    my $number = any2dec($b, $c);
                    print STDOUT "$number\n";
                } else {
                    print STDOUT "Error\n"; 
                    print STDERR "Check number notation\n";  
                }
            }
            else {
                print STDOUT "Error\n"; 
                print STDERR "Operation not supported\n";    
            }
        }
    } else {
        print STDOUT "Error\n";
        print STDERR "Error! Not enough values\n";
    }
}

close ( FH );

exit 0;
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость