PHP 使用位运算实现四则运算的代码

吾爱主题 阅读:130 2021-09-27 11:26:00 评论:0

计算机最基本的操作单元是字节,一个字节由8个位组成,一个位只能存储一个0或1。所有数据在计算机中都是采用二进制,即 1 和 0 的编码存储和运算。

这次尝试在 PHP 中使用位运算实现四则运算,首先介绍一些基本概念:

原码:将最高位作为符号位(0表示正,1表示负),其它数字位代表数值本身的绝对值

反码:正数反码和原码一样;如果是负数,符号位不变,其余各位取反

补码:正数补码和原码一样;负数补码为反码加 1

计算机中的数使用 补码  的形式存储

⒈ 加法

二进制中只有 0 和 1,0 + 0、0 + 1 都不需要进位,但 1 + 1 则需要进位。所以,首先通过 抑或 运算得到不需要进位的那些位相加的结果。然后进行 与 运算,当相加的两位都为 1 时结果为 1。所以如果与运算的结果大于 0 说明需要进位,此时将与运算的结果按位左移 1 位,此时将左移的结果与抑或运算得到的结果重新进行上述的运算过程,直到与运算的结果为 0。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php    function add( $summand , $addend )    {      $sum = $summand ^ $addend ;      // 判断进位      $carry = $summand & $addend ;      while ( $carry <<= 1) {        $summand = $sum ;        $addend = $carry ;        $sum = $summand ^ $addend ;        $carry = $summand & $addend ;      }      return $sum ;    }

⒉ 减法

减法可以看作是减数为负数的加法,例如 2 - 1 可以看作是 2 + (-1)。

?
1 2 3 4 5 6 7 8 9 10 <?php    require 'addition.php' ;      function subtract( $minuend , $subtrahend )    {      // 先求得减数的补码,然后求和      $subtrahend = add(~ $subtrahend , 1);        return add( $minuend , $subtrahend );    }

⒊ 乘法

乘法也可以看作是加法的变种,例如 m * n 可以看作是 n 个 m 相加的结果。但乘法使用位运算还有更快捷的实现方式。例如 3 * 10:3 的二进制表示为 0011,10 的二进制表示为 1010

0 0 1 1

×      1 0 1 0

————————————

0 0 0 0

0 0 1 1 0

0 0 0 0 0 0

0 0 1 1 0 0 0

————————————

0 0 1 1 1 1 0

由上图可以看出,乘法计算的结果为:当乘数的位的值为 1 时,将被乘数按位左移相应的位数,最后将这些按位左移后得到的结果相加及时最后的结果。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?php  require 'addition.php' ;    function multiply( $multiplicand , $multiplicator )    {      // 判断符号位      $flag = ( $multiplicand ^ $multiplicator ) < 0 ? false : true;      // 被乘数和乘数取绝对值      $multiplicand = $multiplicand < 0 ? add(~ $multiplicand , 1) : $multiplicand ;      $multiplicator = $multiplicator < 0 ? add(~ $multiplicator , 1) : $multiplicator ;      $product = 0;      $multiplicator = decbin ( $multiplicator );      $length = strlen ( $multiplicator );      for ( $i = 0; $i < $length ; $i ++) {        if ( $multiplicator [ $i ]) {          $product += $multiplicand << $length - $i - 1;        }      }      if (! $flag ) {        $product = add(~ $product , 1);      }      return $product ;    }

⒋ 除法

同乘法类似,除法可以看作是被除数可以减去多少个除数。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <?php    require 'addition.php' ;      function divide( $dividend , $divisor )    {      // 判断符号位      $flag = ( $dividend ^ $divisor ) < 0 ? false : true;      // 取得被除数符号位      $dividend_flag = $dividend < 0 ? false : true;      // 取绝对值      $dividend = $dividend < 0 ? add(~ $dividend , 1) : $dividend ;      $divisor = $divisor < 0 ? add(~ $divisor , 1) : $divisor ;        $quotient = 0;      $remainder = 0;        if ( $dividend < $divisor ) {        // 被除数小于除数的情况        $remainder = $dividend ;        return 'quotient = ' . $quotient . ' remainder = ' . $remainder ;      }        while ( $dividend >= $divisor ) {        $i = 0;        $mul_divisor = $divisor ;          while ( $dividend >= ( $mul_divisor << 1)) {          $i ++;          $mul_divisor <<= 1;        }          $dividend -= $mul_divisor ;        $quotient += 1 << $i ;      }       $remainder = $dividend ;     if (! $flag ) {       $quotient = add(~ $quotient , 1);     }     if (! $dividend_flag ) {       $remainder = add(~ $remainder , 1);     }       return 'quotient = ' . $quotient . ' remainder = ' . $remainder ;    }

以上。

需要指出的是,上面的代码在实现过成功并没有考虑数据的溢出。 两个很大的数相加可能会溢出;正数减负数也可能溢出;两个大数相乘也会溢出;任何数除以 0 都会溢出。

总结

以上所述是小编给大家介绍的PHP 使用位运算实现四则运算的代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

原文链接:https://juejin.im/post/5e198d27e51d4531220262e3

可以去百度分享获取分享代码输入这里。
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容