Perl中的位操作

Tor*_*ren 4 perl bit-manipulation

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

我在我的程序中使用:

Sub BitOperationOnAttr

{

my $a="";

MyGetFunc( $a);

$a |= 0x00000008;

MySetFunc( $a);

}
Run Code Online (Sandbox Code Playgroud)

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

问题:

  1. 如果使用$a |= 0x00000008;是对的?

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

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

Mic*_*man 23

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

  • 位运算符&,|~.
  • packunpack功能.
  • vec功能.

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

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

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

vec($value, 3, 1) = 1;  # set bit
vec($value, 3, 1) = 0;  # clear bit
if (vec($value, 3, 1))  # check bit
Run Code Online (Sandbox Code Playgroud)

pack并且unpack更适合处理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认同)

psm*_*ars 5

  1. 如果使用$ a | = 0x00000008; 是正确的 ?

是的,这很好.

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

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

我假设你有一个像上面这样的字符串,并希望使用正则表达式来提取"0x8".在这种情况下,像:

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

应该管用.