ホームページ  >  記事  >  バックエンド開発  >  ビット演算を使用して PHP で加算、減算、乗算、除算の演算を実装する方法についての簡単な説明

ビット演算を使用して PHP で加算、減算、乗算、除算の演算を実装する方法についての簡単な説明

青灯夜游
青灯夜游転載
2021-07-08 18:45:323170ブラウズ

PHP はビット演算をどのように使用して四則演算を実装しますか?この記事では、PHPでビット演算を使って四則演算(加減乗除)を実現する方法を紹介します。

ビット演算を使用して PHP で加算、減算、乗算、除算の演算を実装する方法についての簡単な説明

#コンピュータの最も基本的な動作単位はバイトです。1 バイトは 8 ビットで構成され、1 ビットには 0 または 1 のみを格納できます。コンピュータ内のすべてのデータはバイナリ、つまり 1 と 0 のエンコーディングで保存および操作されます。

今回は、PHP でビット演算を使用して四則演算を実装してみます。まず、基本的な概念をいくつか紹介します:

元のコード: 最上位ビットを符号ビットとして使用します (0 を意味します)正、1 は負を意味します)、他の数字は値自体の絶対値を表します

補数コード: 正の数の補数コードは元のコードと同じです。負の場合は、数値、符号ビットは変更されず、残りの桁は補数になります。

コード: 正の数値の補数は元のコードと同じです。負の数値の補数は逆コードに 1

を加えたものです。コンピュータは の補数形式で格納されます

⒈ 加算

バイナリには 0 と 1 だけがあります0 0 も 0 1 も桁上げは必要ありませんが、1 1 は桁上げが必要です。したがって、最初に または 演算によってキャリーを必要としないビットの加算結果を取得します。次に、 の演算を実行し、加算された 2 つのビットが両方とも 1 の場合、結果は 1 になります。したがって、AND 演算の結果が 0 より大きい場合はキャリーが必要であることを意味し、このとき AND 演算の結果を 1 ビット左にシフトします。 OR演算の結果にshiftを組み合わせ、AND演算の結果が0になるまで上記の演算処理を繰り返します。

<?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)。

<?php
    require &#39;addition.php&#39;;

    function subtract($minuend, $subtrahend)
    {
        //  先求得减数的补码,然后求和
        $subtrahend = add(~$subtrahend, 1);

        return add($minuend, $subtrahend);
    }

⒊ 乗算

乗算は加算の変形とみなすこともできます。たとえば、m * n とみなすことができます。 as n m を加算した結果。ただし、ビット単位の演算を使用して乗算をより高速に実装する方法があります。たとえば、3 * 10: 3 のバイナリ表現は 0011、10 のバイナリ表現は 1010

0 0 1 1

× 1 0 1 0

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

0 1 1 0 0 0

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

0 0 1 1 1 1 0

上の図から、乗算の計算の結果が次のようになっていることがわかります。乗数のビットの値が 1 の場合、被乗数はは対応する桁数だけ左にシフトされ、最後にビット単位の左シフト後に得られた結果が最終結果に加算されます。

<?php
    require &#39;addition.php&#39;;

    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;
    }

⒋ 割り算

掛け算と同様に、割り算は、被除数から除数をいくつ引くことができるかということとして見ることができます。

<?php
    require &#39;addition.php&#39;;

    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 &#39;quotient = &#39; . $quotient . &#39; remainder = &#39; . $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 &#39;quotient = &#39; . $quotient . &#39; remainder = &#39; . $remainder;
    }
以上。

上記のコードは、正常に実装された場合にはデータ オーバーフローを考慮していないことに注意してください。

非常に大きな 2 つの数値の加算もオーバーフローする可能性があります。負の数値から正の数値を減算することもオーバーフローする可能性があります。2 つの大きな数値の乗算もオーバーフローする可能性があります。0 で割った数値もオーバーフローする可能性があります。

推奨学習: 「

PHP ビデオ チュートリアル

以上がビット演算を使用して PHP で加算、減算、乗算、除算の演算を実装する方法についての簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。