Skip to content

Instantly share code, notes, and snippets.

@doug65536
Last active September 6, 2018 06:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doug65536/8beb52a93f1e7384486ab87b4a1fd289 to your computer and use it in GitHub Desktop.
Save doug65536/8beb52a93f1e7384486ab87b4a1fd289 to your computer and use it in GitHub Desktop.
Writing 16 bit value 0xbbaa (ByteCount = 2) at various offsets
+-----------------------------------+---------------------------------------------------------+
| DW | |
+--------+--------+--------+--------+-------------+-------------------------------------------+
+ byte 3 | byte 2 | byte 1 | byte 0 | Address & 3 | ((LowerAddress & 3) + ByteCount + 3) >> 2 |
+--------+--------+--------+--------+-------------+-------------------------------------------+
| | | bb | aa | 0 | ((0 & 3) + (2 + 3)) >> 2 = 5 / 4 = 1 |
| | | | | | |
| | bb | aa | | 1 | ((1 & 3) + (2 + 3)) >> 2 = 6 / 4 = 1 |
| | | | | | |
| bb | aa | | | 2 | ((2 & 3) + (2 + 3)) >> 2 = 7 / 4 = 1 |
| | | | | | |
| aa | | | | 3 | ((3 & 3) + (2 + 3)) >> 2 = 8 / 4 = 2 |
+--------+--------+--------+--------+-------------+-------------------------------------------+
@buttercutter
Copy link

buttercutter commented Dec 5, 2017

How is the table above equivalent to computing the value of ROUNDUP(x, pow2) = ((x + (pow2 - 1)) & ~(pow2 - 1)) ?

@doug65536
Copy link
Author

doug65536 commented Dec 5, 2017

The "bytecount + 3" part is based on that. pow2 is 2 for 32 bit values. (2 to the power of 2) minus 1 == 3

Instead of &, it uses >>, which essentially discards the bits that & would have masked off.

@buttercutter
Copy link

Do you have any comments on the following ?

[21:36] <promach_> geist: the ROUNDUP function does not work for x=2 and pow=3 or pow2=3x3=9
[21:36] <promach_> did I miss anything ?
[21:37] <promach_> geist: ((2 + (9 - 1)) & ~(9 - 1)) should return the value of 3 instead of 2

@doug65536
Copy link
Author

pow2 must be a power of two, otherwise it won't work. That is why it is named "pow2"

@buttercutter
Copy link

buttercutter commented Dec 6, 2017

[12:58] promach_, regarding last gist comment. pow2 must be a power of two, otherwise it won't work
[12:58] <promach_> yeah, PCIe is a computer protocol, and it should follow the binary rule of computing

[13:00] 2^n is guaranteed to have n zeros in the least significant bits, and bit n is guaranteed to be 1, and all bits to the left of bit n are guaranteed to be zero
[13:00] == M_D_K [~M_D_K@voidi.ca] has quit [Quit: ZNC - http://znc.in]
[13:01] (2^n)-1 is guaranteed to have (n-1) 1's in the least significant bits, and all bits >= bit n are guaranteed to be zero
[13:01] ^ that is why it works

[13:03] promach_, pow2-1 is n 1s, ~(pow2 - 1) has all 1s from position n+1 onwards, (x + (pow2-1)) has a 1 in position n+1 and 0s onwards

why does ROUNDUP(x, pow2) = ((x + (pow2 - 1)) & ~(pow2 - 1)) round up to the next integer in pow (where pow2 must be a power of two ) ?

[21:33] promach_: there are two cases to consider - first when x is already multiple of pow2, then the operation is no-op, check yourself
[21:34] promach_: otherwise, x + pow2 - 1 will be >= next multiple of pow2
[21:34] and & ~(pow2-1) just clears low bits

https://www.reddit.com/r/math/comments/7hxr3z/poweroftwo_integer_roundup_maths_algorithms/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment