contributed by < yaohwang99
>
1
a & b & 1
2
Here we can look at some properties:
x ^ x
is equivalent to 0
x ^ 0
is equivalent to x
x ^ (x ^ y)
is equivalent to (x ^ x) ^ y
and is equivalent to y
x & ~0
is equivalent to x
, x & 0
is equivalent to 0
We would like to return a
when a > b
and return b
otherwise.
((EXP4) & -(EXP5))
is 0
when a <= b
, therefore, assume EXP5 is a > b
a > b
, then when a > b
, the return value a ^ ((EXP4) & 1)
equals b
, therefore, EXP4 is a ^ b
3
v > u
, v -= u
, and vice versa.v == u
COND: v
RET: u << shift
4
out
stores the index of each 1
in the bit map, for example, if we use 3 unsigned 8 bit integer as an array, then out == {0, 6, 9, 12, 18, 19, 23}
and pos
is 7
Bit Hack #7 shows how to isolate the rightmost 1-bit.
EXP6: -x | x
5
Consider the example where
MMM: list_add
EEE: &heads[remainder % size]
345238095
, the question is where to put the parenthesis.(
before the target and insert )
at the end of the string.PPP: pos--
The following code is an implementation without list.
Note that:
remainder
is big enough, remainder * 10
will need more than 32 bits to store.6
data alignment
If we declare a structure like this
Alignment will be done by default. The address of a
will be 4 bytes after the address of c
.
Implement the characteristic into macro, we can get the result by subtracting the address of the two pointer.
M:_h
X: 0
7
From Faster Remainder by Direct Computation,
In our case, for
n * M
will be implicitly converted to uint32_t
, which is the 32 less significant bit, which equals to .
Therefore, n * M <= M - 1
is the same as from proposition 1.
M3 can also be interpreted as the decimal part of shifted left 64 bits.
Which will be 01010101…2
M5 can be interpreted as the decimal part of shifted left 64 bits.
Which will be 001100110011…2
The 64 least significant bits is the decimal part of the quotient.
number | start | length |
---|---|---|
3 | 0 | 4 |
5 | 4 | 4 |
15 | 0 | 8 |
none | 8 | 2 |
From the above tabel, we can easily deduct that KK1: div3
, KK2: div5
.
For the starting position, we can see that when the number divides 3, the starting position is always zero, so we need to shift more then 1 to clear every bit. Therefore, KK3: div3 << 2
.
Note that in line 17, the default starting index should be 8, not 9.
To avoid printf
, I modified the code and compare result using perf
.
Notice that the naive version is not slower.
Look at the assembly code, if(i % 3)
is:
2863311531
is 0xAAAAAAB
, which is , which means that compiler converts division to multiplication just like we did.
Furthermore, the naive version does not call strncpy
but the bitwise version does
strncpy(fmt,"FizzBuzz",8)
is converted to
strncpy(fmt, &"FizzBuzz%u"[(8 >> div5) >> (div3 << 2)], length)
is converted to