Perl 数学::BaseConvert使用奇怪的基号,如23或1000
我刚刚找到了perl模块Math::BaseConvert。我必须把数字转换成不同基数的奇怪数字。不仅是基数2、8、16,还有23134到1000。(这是平衡目录中文件树的部分任务) 我来不了。阅读CPAN模块的测试也让我感到困惑。所以我写了一个小测试,也许你能告诉我出了什么问题,结果是: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
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是这样做的吗我已经很优雅了!