펄은 큰 숫자와 작은 문제가, 당신의 숫자는 정말 큰 단지 use bignum
경우. 이것은 무한 정밀도의 산술을 투명하게 가능하게합니다.
귀하의 전화 번호 21767823360은 약 35 비트가 필요합니다. 내 perl
은 64 비트 정수 (지원을 확인하려면 perl -v
참조)로 작성되었으므로 전화 번호가 너무 많지 않습니다.
# pseudocode
let "digits" be the array containing all the digits of our representation.
# the size of digits is the base of our new representation
# the digits are sorted in ascending order.
#digits[0] is zero.
var "n" is the number we want to represent.
var "size" is the number of digits of the new representation.
# floor(ln(n)/ln(digits.size))
var "representation" is the empty string.
while size >= 0:
representation ← representation.concat(digits[n/digits.length^size]).
n ← n.modulo(digits.length^size).
size ← size - 1.
return representation.
예 펄 :
#!/usr/bin/perl
use strict; use warnings;
use Carp;
sub base_n {
my ($number, $base, $max_digits, $pad) = @_;
defined $number or croak "Undefined number for base_n";
$number == int $number and $number >= 0
or croak "The number has to be a natural number for base_n";
defined $base or croak "Undefined base for base_n";
$base == int $base and $base > 0
or croak "The base has to be a positive integer for base_n";
my @digits = (0 .. 9, "A" .. "Z");
$base <= @digits or croak "base_n can only convert to base-" . @digits . " max.";
@digits = @digits[0 .. $base - 1];
my $size = $number ? int(log($number)/log($base)) : 0; # avoid log(0)
if (defined $max_digits) {
$size < $max_digits
or croak "The number $number is too large for $max_digits digits in base $base.";
$size = $max_digits - 1 if $pad;
}
my $representation = "";
while ($size >= 0) {
$representation .= $digits[$number/@digits**$size];
$number %= @digits**$size;
$size--;
}
if (wantarray) {
my $checksum = substr $representation, -1;
return $representation, $checksum;
} else {
return $representation;
}
}
상응 (불완전한) 단위 테스트 :
알고리즘베이스 N은 단순 숫자로 변환하는
use Test::More;
my $n = 21767823360;
ok "A000000" eq base_n($n => 36), "simple";
ok "A000000" eq base_n($n => 36, 8), "valid constraint";
ok "0A000000" eq base_n($n => 36, 8, 1), "padding";
ok ! eval { base_n($n => 36, 6); 1 }, "invalid constraint";
ok "0" eq (base_n($n => 36))[1], "checksum (1)";
ok "A" eq (base_n($n+10 => 36))[1], "checksum (2)";
ok "0" eq base_n(0 => 36), "zero: simple";
ok "0"x8 eq base_n(0 => 36, 8, 1), "zero: padding";
ok ! eval { base_n($n => 0.7); 1 }, "invalid base";
ok ! eval { base_n(0.7 => 36); 1 }, "invalid number";
ok $n == base_n($n => 10), "round-trip safety";
ok $n eq base_n($n => 10, length $n, 1), "round-trip safety: padding";
done_testing;
수도 당신이 시도한 코드를 보여줄 수 있습니까? –
@divid는 내가 시도한 코드를 추가했다 .. –