Perl 数学::BaseConvert使用奇怪的基号,如23或1000

Perl 数学::BaseConvert使用奇怪的基号,如23或1000,perl,math,numbers,rebase,Perl,Math,Numbers,Rebase,我刚刚找到了perl模块Math::BaseConvert。我必须把数字转换成不同基数的奇怪数字。不仅是基数2、8、16,还有23134到1000。(这是平衡目录中文件树的部分任务) 我来不了。阅读CPAN模块的测试也让我感到困惑。所以我写了一个小测试,也许你能告诉我出了什么问题,结果是: ok 1 - use Math::BaseConvert; ok 2 - Convert number '23' (base10) to '27' (base8) not ok 3 - Convert num

我刚刚找到了perl模块Math::BaseConvert。我必须把数字转换成不同基数的奇怪数字。不仅是基数2、8、16,还有23134到1000。(这是平衡目录中文件树的部分任务)

我来不了。阅读CPAN模块的测试也让我感到困惑。所以我写了一个小测试,也许你能告诉我出了什么问题,结果是:

ok 1 - use Math::BaseConvert;
ok 2 - Convert number '23' (base10) to '27' (base8)
not ok 3 - Convert number '23' (base10) to '23' (base32)
#   Failed test 'Convert number '23' (base10) to '23' (base32)'
#   at test_math_baseconvert.pl line 35.
#          got: 'N'
#     expected: '23'
not ok 4 - Convert number '64712' (base10) to '64:712' (base1000)
#   Failed test 'Convert number '64712' (base10) to '64:712' (base1000)'
#   at test_math_baseconvert.pl line 35.
#          got: '-1'
#     expected: '64:712'
1..4
# Looks like you failed 2 tests of 4.
测试程序如下所示:

#!/usr/bin/perl
use strict;
use warnings;
use Test::More;

use_ok( 'Math::BaseConvert', '1.7' );

my @lines = (
    {

        # http://www.wolframalpha.com/input/?i=23+from+base+10+to+base+16
        old_number => '23',
        old_base   => 10,
        new_number => '27',
        new_base   => 8,
    },
    {

        # http://www.wolframalpha.com/input/?i=23+from+base+10+to+base+32
        old_number => '23',
        old_base   => 10,
        new_number => '23',    # stays same
        new_base   => 32,
    },
    {

        # http://www.wolframalpha.com/input/?i=64712+from+base+10+to+base+1000
        old_number => '64712',
        old_base   => 10,
        new_number => '64:712',
        new_base   => 1000,
    },
);
for my $line (@lines) {
    cmp_ok(
        Math::BaseConvert::cnv(
            $line->{old_number}, $line->{old_base}, $line->{new_base}
        ),
        'eq',
        $line->{new_number},
        sprintf(
            "Convert number '%s' (base%d) to '%s' (base%d)",
            $line->{old_number}, $line->{old_base},
            $line->{new_number}, $line->{new_base}
        )
    );
}

done_testing();

您似乎期望十进制输出,“数字”是由
分隔的十进制数字

数学::BaseConvert不会这样做。它只支持每个数字有一个字符。 默认情况下,使用的数字是
'0'..'9','A'..'Z','A'..'Z','u'
,尽管您可以提供自己的列表(并且您必须这样做才能支持高达基数1000)。

显示大于基数
16
的基数的方法是用冒号分隔数字。这并没有什么错,因为他们使用css样式显示这些数字,学习冒号的阴影,使其更清楚地显示他们在做什么。但他们也添加了一条信息,说明他们显示的数字到底有多少,因为“1:1617(2位数)”不够明显

该方法和其他此类模块使用的是扩展数字字符集,就像对数字
0-9A-F
所做的那样,以包括字母表中的前6个字母。对于基数为32的数字,字符集为
0-9A-V
。如果
N
是字母表中的第14个字母,则它是以32为底的
23
的适当表示形式

如果要对大于16的数字使用冒号表示,可以使用模块,也可以使用自己的解决方案

#!/usr/bin/perl
use strict;
use warnings;
use Test::More;

use_ok( 'Math::BaseConvert', '1.7' );

my @lines = (
    # Old_Number Old_Base New_Number New_Base
    [qw(23 10 27 8)],              # http://www.wolframalpha.com/input/?i=23+from+base+10+to+base+16
    [qw(23 10 23 32)],             # http://www.wolframalpha.com/input/?i=23+from+base+10+to+base+32
    [qw(64712 10 64:712 1000)],    # http://www.wolframalpha.com/input/?i=64712+from+base+10+to+base+1000
);

for my $line (@lines) {
    cmp_ok(
        base10toN(@$line[0,3]),
        'eq',
        $line->[2],
        sprintf("Convert number '%s' (base%d) to '%s' (base%d)", $line->[0], 10, @$line[2,3])
    );
}

sub base10toN {
    my ($num, $base) = @_;

    return Math::BaseConvert::cnv($num, 10, $base)
        if $base <= 16;

    my @digits = ();
    while (1) {
        my $remainder = $num % $base;
        unshift @digits, $remainder;
        $num = ($num - $remainder) / $base
            or last;
    }
    return join ':', @digits;
}

done_testing();
#/usr/bin/perl
严格使用;
使用警告;
使用测试::更多;
使用_ok('Math::BaseConvert','1.7');
我的@lines=(
#旧号码旧号码新号码新号码新号码
[qw(23 10 27 8)],#http://www.wolframalpha.com/input/?i=23+从+base+10+到+base+16
[qw(23 10 23 32)],#http://www.wolframalpha.com/input/?i=23+从+base+10+到+base+32
[qw(647121064:7121000)],#http://www.wolframalpha.com/input/?i=64712+从+base+10+到+base+1000
);
对于我的$line(@lines){
好的(
基准10吨(@$line[0,3]),
"情商",,
$line->[2],
sprintf(“将编号“%s”(基数%d)转换为“%s”(基数%d)”,$line->[0],10,@$line[2,3])
);
}
底基10吨{
我的($num,$base)=@;
返回数学::BaseConvert::cnv($num,10,$base)

如果是$base,你能解释一下为什么你认为是“23”基数10和基数32之间应保持不变?高于
10
的基数通常会添加额外的字符来表示额外的数字。例如,在十六进制表示法中,
10
15
A
F
表示。同样,基数
32
中的
23
应为14字母表中的第个字母,即
N
。请阅读文档以了解它所做的更多细节。特别是
dig
方法。我原以为CPAN中的Perl模块会将每个数字N重设为任何新的基数。但它们都卡在字母表的末尾。感谢您的努力!我必须自己编写,Miller是这样做的吗我已经很优雅了!