【问题标题】:Bit operations in PerlPerl 中的位操作
【发布时间】:2013-12-14 04:20:46
【问题描述】:

我有一个属性(32 位长),每个位负责特定的功能。我正在编写的 Perl 脚本应该打开第 4 位,但保存之前对其他位的定义。

我在我的程序中使用:

Sub BitOperationOnAttr

{

my $a="";

MyGetFunc( $a);

$a |= 0x00000008;

MySetFunc( $a);

}

** MyGetFunc/ MySetFunc 我自己知道读取/修复值的函数。

问题:

  1. $a |= 0x00000008; 的用法是否正确?

  2. 如何通过正则表达式从我拥有的字符串中提取十六进制值:例如:

"属性:Somestring: value (8 long (0x8))"

【问题讨论】:

  • 您的问题不相关;它们应该单独张贴。这让有类似问题的其他人更容易找到他们。

标签: perl bit-manipulation


【解决方案1】:

Perl 提供了几种处理二进制数据的方法:

  • 按位运算符&|~
  • packunpack 函数。
  • vec 函数。

您的场景听起来像是一组打包的标志。位运算符非常适合这种情况:

my $mask = 1 << 3;   # 0x0008
$value |=  $mask;    # set bit
$value &= ~$mask;    # clear bit
if ($value & $mask)  # check bit

vec 设计用于位向量。 (每个元素的大小相同,必须是 2 的幂。)它也可以在这里工作:

vec($value, 3, 1) = 1;  # set bit
vec($value, 3, 1) = 0;  # clear bit
if (vec($value, 3, 1))  # check bit

packunpack 更适合处理 C 结构或字节序之类的东西。

【讨论】:

  • 我投了赞成票,但缺少一些非常重要的东西:vec 对字符串进行操作!如果我们使用数字;说:$val=5; printf("b%08b",$val);(这给出了b00000101)——然后可以看到“校验位”语法,比如:for($ix=7;$ix&gt;=0;$ix--) { print vec($val, $ix, 1); }; print "\n"; 将不起作用(它给出了00110101,这不是同一个数字)。正确的是将数字转换为ASCII字符,即print vec(sprintf("%c", $val), $ix, 1);
【解决方案2】:
  1. 如果使用 $a |= 0x00000008;对吗?

是的,这很好。

  1. 如何通过正则表达式从我拥有的字符串中提取十六进制值:例如:

"属性:Somestring: value (8 long (0x8))"

我假设您有一个像上面这样的字符串,并且想要使用正则表达式来提取“0x8”。在这种情况下,类似:

if ($string =~ m/0x([0-9a-fA-F]+)/) {
    $value = hex($1);
} else {
    # string didn't match
}

应该可以。

【讨论】:

  • 感谢您的快速回答。你告诉我解决问题的正确方法
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 2011-09-14
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
相关资源
最近更新 更多