3 ms·
The calculation `red = r << 5 | r << 2 | r >> 1` is equivalent to `red = floor(r * (1 << 5 | 1 << 2 | 1 >> 1))`, which is `red = floor(r * 36.5)`.
by RetroSpark 7y ago
The calculation `red = r << 5 | r << 2 | r >> 1` is equivalent to `red = floor(r * (1 << 5 | 1 << 2 | 1 >> 1))`, which is `red = floor(r * 36.5)`.
- byuu 7y agoI thought it would be good to get people familiar with bit-twiddling, as you will be doing a whole lot of that when writing retro emulators. This is one of my favorite sites on the internet: https://graphics.stanford.edu/~seander/bithacks.html https://graphics.stanford.edu/~seander/bithacks.html
- RetroSpark 7y agoAbsolutely, couldn't agree more. I just wanted to clarify why the bit-shifting approach was equivalent to the previous comment's multiplication by 36.4. > This is one of my favorite sites on the internet: https://graphics.stanford.edu/~seander/bithacks.html https://graphics.stanford.edu/~seander/bithacks.html Yes - I also enjoyed the book "Hacker's Delight", but haven't got round to reading the second edition yet.
- myrmi 7y agoThe first time I found this page, I lost the rest of my afternoon reading it through. Highly recommend.
- fps_doug 7y agoBut please keep in mind that today's compilers are (most of the time) very smart. Hacker's Delight is somewhat outdated today. There's no need anymore for writing "x << 2" instead of "x * 4". I recommend Matt Godbolt's Talk(s) about compiler cleverness: https://www.youtube.com/watch?v=bSkpMdDe4g4 https://www.youtube.com/watch?v=bSkpMdDe4g4 (see the 30 minute mark for the multiplication example)
- FreeFull 7y agoI'd say it's about intent. Depending on the context, "x * 4" is less clear than the bitshift (For example, when packing multiple values into an integer)
- kevincox 7y agoThe point isn't "always do multiplication" but to do what makes logical sense. Don't pick your operators for performance, pick them for readability. The compiler will handle the performance aspect for you.
- jameshart 7y agoI think I get what you're aiming at in your explanation, but you're not being quite explicit enough about how those shifts map to multiplications, and having to assume a world where 1 >> 1 is 0.5 is... consistent, but counterintuitive. But I think what you're aiming to say is: r << 5 | r << 2 | r >> 1 amounts (because r is constrained to three bits) to being the same as r << 5 + r << 2 + r >> 1 And r << 5 is r * 32, r << 2 is r * 4, and r >> 1 is floor(r / 2) So the whole thing is r * 32 + r * 4 + floor(r * 0.5) which is the same as floor(r * 32 + r * 4 + r * 0.5) or floor(r * 36.5)