在 PHP 中翻转位


Flipping bits in PHP

好的,问题是:您将获得一个文件中要读取的 32 位无符号整数列表。您需要通过翻转二进制表示中的位来输出无符号整数的列表(即必须设置未设置位,并且必须取消设置位)。

示例输入为:

3
2147483647
1
0

示例输出为:

2147483648
4294967294
4294967295

其中输入中的 3 是行数。

<?php
$_fp = fopen("php://stdin", "r");
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
$t = fgets($_fp);

for($i=0;$i<$t;$i++){
    $line = fgets($_fp);
    $binLine = decbin($line);
    $reverse = strrev($binLine);
    echo bindec($reverse)."'n";
}
fclose($_fp);
?>

这是怎么错的?我应该改用按位运算符吗?

你说"必须设置未设置位,并且必须取消设置位"。这是用1 XOR每个数字的每个位的结果。

代码应为:

for($i=0;$i<$t;$i++){
    $line = fgets($_fp);
    echo(($line ^ 0xFFFFFFFF)."'n");       # 32-bit full of '1'
}

32 位二进制值11111111111111111111111111111111并转换为4294967295的十进制。然后,在输入值和4294967295之间执行 XOR。

function flippingBits($n) {
   return $n ^ 4294967295;
}
$result = flippingBits(3);//any input
echo( $result . "'n");

使用 bindec(str_repeat("1", 32)) 创建蒙版并应用翻转运算符^

decbin(2147483648^bindec(str_repeat("1", 32))) # "1111111111111111111111111111111"

对于具有较低值的整数,如果需要将它们转换为 32 位整数,可以使用sprintf

sprintf('%032d', 1) # "00000000000000000000000000000001"
decbin(sprintf('%032d', 1)^bindec(str_repeat("1", 32))) # "11111111111111111111111111111110"

你可以试试那个代码

<?php
$bin = sprintf( "%032d", decbin( 0 ));
$out = "";
for( $i = 0; $i < strlen($bin); $i++ ) {
    $char = substr( $bin, $i, 1 );
    $out .= ($char == 1 ) ? 0 : 1;
}
$dec = bindec($out);
print($out."'n");
print($dec);
?>