challenge 16進数から10進数の変換

16進数を10進数に変換してください。

ただし、入出力は文字列とし、次の変換は最低必ずできなければいけないこととします。

  1. 0x12437308CCB6 →20080902065334

2.0x2C9C1227FC6520B →200904012311450123

あわせて、扱える最大の整数も明らかにしてください。

Posted feedbacks - Perl

変換対象の16進数文字列はコマンドライン引数から。

use bigint で使用されるMath::BigIntには ”Arbitrary size integer" って書いてあるので、任意長の整数を扱えるのではないかと思いますが。

1
2
use bigint;
print "".hex shift;

引数は、コマンドラインで指定します。
短い桁数の計算に分解しているので、特に制限はありません。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use strict;
my $base = "0123456789abcdef";
my $num_16 = shift; $num_16 =~ s/^0x//; $num_16 = "\L$num_16";
my @num_16 = reverse split //, $num_16;
my @result;

foreach my $idx (0 .. $#num_16) {
  my $n = index($base, $num_16[$idx]);
  next unless $n;
  my @temp = calc($n, $idx);
  foreach my $idx (0 .. $#temp) {
    $result[$idx] += $temp[$idx];
    if ($result[$idx] > 9) {
      $result[$idx] -= 10; $result[$idx + 1]++;
    }
  }
}
print reverse(@result), "\n";

sub calc {
  my @work = reverse split //, shift(); my $x = shift;

  while ($x--) {
    $_ = $_ * 16 foreach @work;
    foreach my $idx (0 .. $#work) {
      if ($work[$idx] > 9) {
        my ($up, $n) = $work[$idx] =~ /^(.+)(.)$/;
        $work[$idx] = $n; $work[$idx + 1] += $up;
      }
    }
    if ($work[$#work] > 9) {
      my ($m, $n) = $work[$#work] =~ /^(.+)(.)$/;
      $work[$#work] = $n; push @work, reverse(split //, $m);
    }
  }
  return @work;
}

Index

Feed

Other

Link

Pathtraq

loading...