Is this the way the compiler divides only with bit-wise operations?

Splitting Using Bitwise Operators

I noticed a post on stackoverflow and saw this fancy method to divide by 3 ( What's the fastest way to divide an integer by 3? ).
It says that: n / 3 = (n * 0x55555556) → 32 . This is multiplied by 0x55555556 and takes the most significant 32 bits. This is true for n to be a 32-bit number. As I started digging the logic, I realized that this can be generalized. For example, if we consider n <128; i.e. 7 bits wide, then:
n / 3 = (n * 0x56) → 8 . So what's going on here? Well, 0x56 = 86 = (258/3) and 258 is the first number greater than 256 that is divisible by 3. Now, 2n = 258n - 256n
==> n = 129n - 128nfor any n; But if we restrict n <128; then 129n - 128n is the same as the quotient of (129n / 128).
==> n = 129n / 128 ; n <128
==> n / 3 = 43n / 128 ; for n <128
==> n / 3 = 86n / 256 ; n <128
==> n / 3 = (n * 0x56) → 8 ;

It's amazing how this can be generalized to other departments. For example, consider division by 5:
4n = 260n - 256n ==> n = 65n - 64n for all n
If n <64; n = 65n / 64
==> n / 5 = 13n / 64 ; n <64
==> n / 5 = (13 * n) → 6 ;
similarly, n / 5 = (52 * n) → 8 ; n <64

We can move along the same lines and deduce that:
n / 5 = 205n / 1024 = (205 * n) → 10 for n <Thousand twenty-four

So, I tried to find a general rule to find n / a for any a ?
first find some power of two (say 2 ^ m ) that is not more than a multiple of a (for example, 1024 in case a = 5); those. 2 ^ m + 1 = ka ; for some k So the problem is to determine k while keeping m fixed (say 32) of: 2 ^ m + 1 = ka . There can be many solutions; once m is fixed, there will be only one.

Then; n / a = k * n → m; for all n <2 ^ m

Now how does the compiler work? Using the formula generator provided by kol in one of the comments:
keeping m = 32 and n = 12; formula generator gives:
a = 3: n / 3 = (1431655766 * n) → 32
a = 5: n / 5 = (858993460 * n) → 32
a = 7: n / 7 = (613566757 * n) → 32

However, when I see my assembly output, I get 1431655766 , 1717986919, and -1840700269, respectively, for division by 3, 5, and 7.
Moreover, if I change the datatype to unsigned int, I get -1431655765 , -858993459, and 613566757 respectively for 3.5 and 7.


As you can see; my prediction for division by 3 happens, but it fails for 5 and 7. it is interesting to see how closely they are related; but i can't explain it
Where did I go wrong in analyzing what the compiler does when splitting?
Code from formula generator ( kol ):
var $a = $("#a"),
$m = $("#m"),
$generate = $("#generate"),
$formula = $("#formula");

$generate.click(function () {
var a = +$a.val(),
    m = +$m.val(),
    m2 = 0,
    k = 0;

if (isNaN(a) || a !== Math.floor(a) || a < 2 || a > Math.pow(2, 31) - 1) {
    alert("Divisor \"a\" must be an integer between 2 and 2^32-1");
    return;
}
m2 = Math.pow(2, m);
k = Math.ceil(m2 / a);
$formula.html("<i>n</i> / " + a + " = (" + k + " * <i>n</i>) &gt;&gt; " + m + "; for all <i>n</i> &lt; " + m2);
});

$generate.click();

      

+3


source to share


1 answer


No, the C compiler does not perform bitwise arithmetic. You don't need to do bitwise arithmetic even in assembly. It runs on a processor of course, and the processor provides the instructions described here: http://en.wikibooks.org/wiki/X86_Assembly/Arithmetic as an abstraction for these operations.



+2


source







All Articles