php实现求二进制中1的个数(右移、&、int32位)(n = n & (n - 1);

一、总结

1、PHP中的位运算符和java和c++一样

2、位移运算符看箭头方向,箭头向左就是左移,左移*2

3、php中整形32位

二、php实现求二进制中1的个数

题目描述:

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
 

最佳代码:

绝对最佳答案及分析:

  1. public class Solution {
  2.     public int NumberOf1(int n) {
  3.         int count = 0;
  4.         while(n!= 0){
  5.             count++;
  6.             n = n & (n - 1);
  7.          }
  8.         return count;
  9.     }
  10. }
答案正确:恭喜!您提交的程序通过了所有的测试用例
分析一下代码: 这段小小的代码,很是巧妙。
如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。
举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。

代码:

  1. <?php
  2.  
  3. function NumberOf1($n)
  4. {
  5. $count = 0;
  6. for($i = 0;$i <32;$i++){ //3、php中整形32位
  7. if(($n >> $i) & 1){ //1、PHP中的位运算符和java和c++一样 2、位移运算符看箭头方向,箭头向左就是左移,左移*2
  8. $count++;
  9. }
  10. }
  11. return $count;
  12. }

三、拓展-php位运算符

位运算符

位运算符允许对整型数中指定的位进行求值和操作。

位运算符
例子 名称 结果
$a & $b And(按位与) 将把 $a 和 $b 中都为 1 的位设为 1。
$a | $b Or(按位或) 将把 $a 和 $b 中任何一个为 1 的位设为 1。
$a ^ $b Xor(按位异或) 将把 $a 和 $b 中一个为 1 另一个为 0 的位设为 1。
~ $a Not(按位取反) 将 $a 中为 0 的位设为 1,反之亦然。
$a << $b Shift left(左移) 将 $a 中的位向左移动 $b 次(每一次移动都表示“乘以 2”)。
$a >> $b Shift right(右移) 将 $a 中的位向右移动 $b 次(每一次移动都表示“除以 2”)。

位移在 PHP 中是数学运算。向任何方向移出去的位都被丢弃。左移时右侧以零填充,符号位被移走意味着正负号不被保留。右移时左侧以符号位填充,意味着正负号被保留。

要用括号确保想要的优先级。例如 $a & $b == true 先进行比较再进行按位与;而 ($a & $b) == true 则先进行按位与再进行比较。

If both operands for the &| and ^ operators are strings, then the operation will be performed on the ASCII values of the characters that make up the strings and the result will be a string. In all other cases, both operands will be converted to integers and the result will be an integer.

If the operand for the ~ operator is a string, the operation will be performed on the ASCII values of the characters that make up the string and the result will be a string, otherwise the operand and the result will be treated as integers.

Both operands and the result for the << and >> operators are always treated as integers.

  1. PHP ini 设定 error_reporting 使用了按位的值,
  2. 提供了关闭某个位的真实例子。要显示除了提示级别
  3. 之外的所有错误,php.ini 中是这样用的:
  4. E_ALL & ~E_NOTICE
  1. 具体运作方式是先取得 E_ALL 的值:
  2. 00000000000000000111011111111111
  3. 再取得 E_NOTICE 的值:
  4. 00000000000000000000000000001000
  5. 然后通过 ~ 将其取反:
  6. 11111111111111111111111111110111
  7. 最后再用按位与 AND(&)得到两个值中都设定了(为 1)的位:
  8. 00000000000000000111011111110111
  1. 另外一个方法是用按位异或 XOR^)来取得只在
  2. 其中一个值中设定了的位:
  3. E_ALL ^ E_NOTICE
  1. error_reporting 也可用来演示怎样置位。只显示错误和可恢复
  2. 错误的方法是:
  3. E_ERROR | E_RECOVERABLE_ERROR
  1. 也就是将 E_ERROR
  2. 00000000000000000000000000000001
  3. E_RECOVERABLE_ERROR
  4. 00000000000000000001000000000000
  5. 用按位或 OR|)运算符来取得在任何一个值中被置位的结果:
  6. 00000000000000000001000000000001

Example #1 整数的 AND,OR 和 XOR 位运算符

<?php
/*
 * Ignore the top section,
 * it is just formatting to make output clearer.
 */

$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
        . ' %3$s (%4$2d = %4$04b)' . "\n";

echo <<<EOH
 ---------     ---------  -- ---------
 result        value      op test
 ---------     ---------  -- ---------
EOH;

/*
 * Here are the examples.
 */

$values = array(0, 1, 2, 4, 8);
$test = 1 + 4;

echo "\n Bitwise AND \n";
foreach ($values as $value) {
    $result = $value & $test;
    printf($format, $result, $value, '&', $test);
}

echo "\n Bitwise Inclusive OR \n";
foreach ($values as $value) {
    $result = $value | $test;
    printf($format, $result, $value, '|', $test);
}

echo "\n Bitwise Exclusive OR (XOR) \n";
foreach ($values as $value) {
    $result = $value ^ $test;
    printf($format, $result, $value, '^', $test);
}
?>

以上例程会输出:

  1. --------- --------- -- ---------
  2. result value op test
  3. --------- --------- -- ---------
  4. Bitwise AND
  5. ( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)
  6. ( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)
  7. ( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)
  8. ( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)
  9. ( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)
  10.  
  11. Bitwise Inclusive OR
  12. ( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
  13. ( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
  14. ( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
  15. ( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
  16. (13 = 1101) = ( 8 = 1000) | ( 5 = 0101)
  17.  
  18. Bitwise Exclusive OR (XOR)
  19. ( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
  20. ( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)
  21. ( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)
  22. ( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)
  23. (13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)

Example #2 字符串的 XOR 运算符

<?php
echo 12 ^ 9; // Outputs '5'

echo "12" ^ "9"; // Outputs the Backspace character (ascii 8)
                 // ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8

echo "hallo" ^ "hello"; // Outputs the ascii values #0 #4 #0 #0 #0
                        // 'a' ^ 'e' = #4

echo 2 ^ "3"; // Outputs 1
              // 2 ^ ((int)"3") == 1

echo "2" ^ 3; // Outputs 1
              // ((int)"2") ^ 3 == 1
?>

Example #3 整数的位移

<?php
/*
 * Here are the examples.
 */

echo "\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";

$val = 4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');

$val = 4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places);

$val = 4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');

$val = 4;
$places = 4;
$res = $val >> $places;
p($res, $val, '>>', $places, 'same result as above; can not shift beyond 0');

echo "\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";

$val = -4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');

$val = -4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');

$val = -4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'same result as above; can not shift beyond -1');

echo "\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";

$val = 4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');

$val = 4;
$places = (PHP_INT_SIZE * 8) - 4;
$res = $val << $places;
p($res, $val, '<<', $places);

$val = 4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places, 'sign bits get shifted out');

$val = 4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side');

echo "\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";

$val = -4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');

$val = -4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places);

$val = -4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side, including sign bit');

/*
 * Ignore this bottom section,
 * it is just formatting to make output clearer.
 */

function p($res, $val, $op, $places, $note = '') {
    $format = '%0' . (PHP_INT_SIZE * 8) . "b\n";

printf("Expression: %d = %d %s %d\n", $res, $val, $op, $places);

echo " Decimal:\n";
    printf("  val=%d\n", $val);
    printf("  res=%d\n", $res);

echo " Binary:\n";
    printf('  val=' . $format, $val);
    printf('  res=' . $format, $res);

if ($note) {
        echo " NOTE: $note\n";
    }

echo "\n";
}
?>

php实现求二进制中1的个数(右移、&、int32位)(n = n & (n - 1);)的更多相关文章

  1. 编程之美Ex1——求二进制中1的个数

    又被阿里机考虐了一次,决定改变策略开始刷题T^T 一个字节(8bit)的无符号整型,求其二进制中的“1”的个数,算法执行效率尽可能高. 最先想到的移位操作,末尾位&00000001,然后右移, ...

  2. 剑指Offer:二进制中1的个数

    题目:输入一个整数,输出该数二进制表示中1的个数. // 二进制中1的个数 #include <stdio.h> int wrong_count_1_bits(int n) // 错误解法 ...

  3. 基于visual Studio2013解决面试题之0410计算二进制中1的个数

     题目

  4. Algorithm --> 二进制中1的个数

    行文脉络 解法一——除法 解法二——移位 解法三——高效移位 解法四——查表 扩展问题——异或后转化为该问题 对于一个字节(8bit)的变量,求其二进制“1”的个数.例如6(二进制0000 0110) ...

  5. leetcode 338. Counting Bits,剑指offer二进制中1的个数

    leetcode是求当前所有数的二进制中1的个数,剑指offer上是求某一个数二进制中1的个数 https://www.cnblogs.com/grandyang/p/5294255.html 第三种 ...

  6. 统计无符号整数二进制中1的个数(Hamming weight)

    1.问题来源 之所以来记录这个问题的解法,是因为在在线编程中经常遇到,比如编程之美和京东的校招笔试以及很多其他公司都累此不疲的出这个考题.看似简单的问题,背后却隐藏着很多精妙的解法.查找网上资料,才知 ...

  7. VIPKID:笔试题(数组中和为0的一对数的数量,十进制转二进制中1的个数)

    1. 求数组中的和为0 的一对数的数量 注意,需要用到set import java.util.Scanner; public class Main{ public static void main( ...

  8. 二进制中1的个数(Java实现)

    问题: 输入一个整数,求其二进制中1的个数 看到这个问题,我们应该想到数的位运算: 解法一:我们每次将此数&1 ,如果结果等于1,证明此数的最后一位是1,,count++: 然后在将数右移一位 ...

  9. Java之一个整数的二进制中1的个数

    这是今年某公司的面试题: 一般思路是:把整数n转换成二进制字符数组,然后一个一个数: private static int helper1(int i) { char[] chs = Integer. ...

随机推荐

  1. golang webservice[ json Martini webframe]

    golang webservice[ json Martini webframe] https://github.com/brunoga/go-webservice-sample 自己修改了一下例子, ...

  2. 交叉编译工具链bash: gcc:no such file or directory

    在进行交叉编译工具链安装时,有三种方法: 1.源码编译,手动安装 2.二进制可执行文件直接安装 3.直接解压工具链,手动修改环境变量 为了方便,我们多用方法3进行安装.但是问题来了,你的工具链制作时有 ...

  3. BZOJ3998: [TJOI2015]弦论(后缀自动机,Parent树)

    Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...

  4. MFC窗口显隐

    使用SetLayeredWindowAttributes可以方便的制作透明窗体,此函数在w2k以上才支持,而且如果希望直接使用的话,可能需要下载最新的SDK.不过此函数在w2k的user32.dll里 ...

  5. Log4j中为什么设计isDebugEnabled()方法

    转自:https://www.jianshu.com/p/e1eb7ebfb21e 先看下面的代码,在真正执行logger.debug()之前,进行了logger.isDebugEnabled()的判 ...

  6. ajax实现简单的点击左侧菜单,右侧加载不同网页

    实现:ajax实现点击左侧菜单,右侧加载不同网页(在整个页面无刷新的情况下实现右侧局部刷新,用到ajax注意需要在服务器环境下运行,从HBuilder自带的服务器中打开浏览效果即可) 原理:ajax的 ...

  7. DataTable +chart控件

    //这是仿你的DataTable //-----开始--------- DataTable dataTable1 = new System.Data.DataTable(); dataTable1.C ...

  8. Mycat快速入门

    1.Mycat介绍 Mycat 是一个开源的分布式数据库系统,是一个实现了 MySQL 协议的的Server,前端用户可以把它看作是一个数据库代理,用 MySQL 客户端工具和命令行访问,而其后端可以 ...

  9. [React & Debug] Quick way to debug Stateless component

    For example we have the following code: const TodoList = (props) => ( <div className="Tod ...

  10. amazeui学习笔记--css(常用组件1)--小徽章Badge

    amazeui学习笔记--css(常用组件1)--小徽章Badge 一.总结 1.am-badge:添加am-badge来声明小徽章对象 <span class="am-badge a ...