Page 220 - ARM 64 Bit Assembly Language
P. 220

208 Chapter 7

                                                    n
                  Recall that, in binary, multiplying by 2 is the same as shifting left by n bits, while multiply-
                  ingby2 −n  is done by shifting right by n bits. Therefore, Eq. (7.2) is just Eq. (7.1) with two
                  shift operations added. The two shift operations cancel each other out. Now, let


                                                            2 n
                                                       m =    .                                 (7.3)
                                                            c

                  We can rewrite Eq. (7.2)as:


                                                 x ÷ c = x × m × 2 −n .                         (7.4)

                  We now have a method for dividing by a constant c which involves multiplying by a different
                  constant, m, and shifting the result. In order to achieve the best precision, we want to choose n
                  such that m is as large as possible with the number of bits we have available.

                  Suppose we want efficient code to calculate x ÷ 23 using 8-bit signed integer multiplication.
                                           2 n
                  Ourfirsttaskistofind m =     such that 01111111 2 ≥ m ≥ 01000000 2 .Inother words, we
                                           c
                  want to find the value of n where the most significant bit of m is zero, and the next most sig-
                  nificant bit of m is one. If we choose n = 11, then


                                                   2 11
                                               m =     ≈ 89.0434782609.
                                                    23

                  Rounding to the nearest integer gives m = 89. In 8 bits, m is 01011001 2 or 59 16 .Wenowhave
                  values for m and n, and therefore we can apply Eq. (7.4) to divide any number x by 23. The
                  procedure is simple: calculate y = x × m, then shift y right by 11 bits.

                  However, there are two more considerations. First, when the divisor is positive, the result for
                  some values of x may be incorrect due to rounding error. It is usually sufficient to increment
                  the reciprocal value by one in order to avoid these errors. In the previous example, the num-
                  ber would be changed from 59 16 to 5A 16 . When implementing this technique for finding the
                  reciprocal, the programmer should always verify that the results are correct for all input val-
                  ues. The second consideration is when the dividend is negative. In that case it is necessary to
                  subtract one from the final result.

                  For example, to calculate 101 10 ÷ 23 10 in binary, with eight bits of precision, we first perform
                  the multiplication as follows:
   215   216   217   218   219   220   221   222   223   224   225