如何在perl中确定数字列表的按位二进制分数?
我正在尝试将一些十进制数和二进制数相互转换。我正在使用以下格式生成的数据:如何在perl中确定数字列表的按位二进制分数?,perl,binary,Perl,Binary,我正在尝试将一些十进制数和二进制数相互转换。我正在使用以下格式生成的数据: Example decimal: 163, Corresponding binary: 10100011 Binary table key: 我希望能够获取一个十进制数,将其转换为二进制,然后使用此查找表打印给定十进制数的属性列表。我可以使用以下代码将十进制转换为二进制: sub dec2bin { my $str = unpack("B32", pack("N", shift)); $str
Example decimal: 163, Corresponding binary: 10100011
Binary table key:
我希望能够获取一个十进制数,将其转换为二进制,然后使用此查找表打印给定十进制数的属性列表。我可以使用以下代码将十进制转换为二进制:
sub dec2bin {
my $str = unpack("B32", pack("N", shift));
$str =~ s/^0+(?=\d)//; # otherwise you'll get leading zeros
return $str;
}
但是,我不知道如何使用查找表。问题是,我有专门为这个表设计的二进制数,比如1000011、10000011、101110011,但是我不知道如何使用这些二进制来获取我们的描述。它们甚至有不同的长度
有人能帮我理解这里发生了什么吗
编辑:这是我找到的另一个查找表。。。也许这更准确/更有帮助?它看起来和我一样,但是来自软件的办公室
任何更简单的方法可能只是检查地图中的每个键,并直接将其与转换后的数字进行比较
sub get_descriptions {
my $binary_num = shift;
my @descriptions;
for my $k (keys %description_map) {
# bitwise comparison
if( $k & $binary_num ) {
# add description because this bit is set
push @descriptions, $description_map{$k};
}
}
# full listing of all descriptions for the set bits
return @descriptions;
}
该表位于base 16中,因此只需转换为base 2即可(我从另一个论坛复制/粘贴了该表,如果它与您的屏幕截图不同,请修复): 等等 要以您的格式获取正确的描述,请使用以下代码:
my @descriptions = (
"the read is paired in sequencing"
,"the read is mapped in a proper pair"
#...
);
check_number(163); # Note that you don't need to convert to binary :)
sub check_number {
my $number = shift;
my $bitmask = 1; # will keep incrementing it by *2 every time
for($i=0; $i < @descriptions; $i++) {
my $match = $bitmask & $number ? 1 : 0; # is the bit flipped on?
print "|$match| $descriptions[$i] | \n";
$bitmask *= 2; # or bit-shift - faster but less readable.
}
}
如果您只想打印匹配的描述,请将循环中的print语句更改为print“$descriptions[$i]\n”,如果$match代码>
这种方法的好处是,它很容易扩展到更长的描述表一旦数字被转换,它在输入中表示的基础就不相关了。在内部,将其视为一个数字
值163表示一个位字段,也就是说,它的每个位都是某个是非问题的答案,并且表格告诉您问题是如何排列的
您可以使用subs为bits指定人类可读的名称,如中所示
sub read_is_paired { $_[0] & 0x0001 }
sub read_is_mapped { $_[0] & 0x0002 }
sub strand_of_mate { $_[0] & 0x0020 }
sub read_is_2nd { $_[0] & 0x0080 }
然后对位字段进行解码
my $flags = 163;
print "read is paired? ", read_is_paired($flags) ? "YES" : "NO", "\n",
"read is mapped? ", read_is_mapped($flags) ? "YES" : "NO", "\n",
"strand of mate = ", strand_of_mate($flags) ? "1" : "0", "\n",
"read is second? ", read_is_2nd($flags) ? "YES" : "NO", "\n";
输出:
read is paired? YES
read is mapped? YES
strand of mate = 1
read is second? YES
阅读是成对的吗?对
读取是否已映射?对
配对股=1
阅读是第二?是的,你打错二进制数了吗?从你的表格描述来看应该是11000011
。我也这么认为!但这不是打字错误。。。这是来自samtools的官方描述网站,这是一套非常重要的生物学家软件工具,我发现其他指南也使用了类似的例子。这让人困惑,因为0x20
映射到32(以10为基数),32位设置在上面的数字中,但表中确实列出了0x20
描述。它列出了0x80
(64,以10为基数)的描述。我从网站上添加了官方的查找表以及网站的链接。感谢概念和编码解决方案!谢谢你的回答!我选择了另一个答案,因为代码对我来说更有意义,但是你的答案也非常有用@jake9115-公认的答案是可扩展性稍差,但您是OP,因此您可以决定哪一个更有用:)@DVK By$number
您的意思是函数的一个参数,对吗?此外,我认为我的解决方案非常干净。@HunterMcMillen-这就是在中重构时发生的情况,而不是在体面的编辑器中:)修复,谢谢
sub read_is_paired { $_[0] & 0x0001 }
sub read_is_mapped { $_[0] & 0x0002 }
sub strand_of_mate { $_[0] & 0x0020 }
sub read_is_2nd { $_[0] & 0x0080 }
my $flags = 163;
print "read is paired? ", read_is_paired($flags) ? "YES" : "NO", "\n",
"read is mapped? ", read_is_mapped($flags) ? "YES" : "NO", "\n",
"strand of mate = ", strand_of_mate($flags) ? "1" : "0", "\n",
"read is second? ", read_is_2nd($flags) ? "YES" : "NO", "\n";
read is paired? YES
read is mapped? YES
strand of mate = 1
read is second? YES