[ruby-core:123827] [Ruby Misc#21690] Inconsistent `rb_popcount64()` definition
Issue #21690 has been reported by daniel.domjan (Dániel Domján). ---------------------------------------- Misc #21690: Inconsistent `rb_popcount64()` definition https://bugs.ruby-lang.org/issues/21690 * Author: daniel.domjan (Dániel Domján) * Status: Open ---------------------------------------- The `rb_popcount64()` function is defined both in `internal/bits.h` and `parser_bits.h`, but the definition of these functions is different on the `#else` branch. ```c // internal/bits.h static inline unsigned int rb_popcount64(uint64_t x) { ... #else x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555); x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333); x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707); x = (x & 0x000f000f000f000f) + (x >> 8 & 0x000f000f000f000f); x = (x & 0x0000001f0000001f) + (x >>16 & 0x0000001f0000001f); x = (x & 0x000000000000003f) + (x >>32 & 0x000000000000003f); return (unsigned int)x; #endif } ``` ```c // parser_bits.h static inline unsigned int rb_popcount64(uint64_t x) { ... #else x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555); x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333); x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707); x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f); x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f); x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f); return (unsigned int)x; #endif } ``` ```diff x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555); x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333); x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707); - x = (x & 0x000f000f000f000f) + (x >> 8 & 0x000f000f000f000f); + x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f); - x = (x & 0x0000001f0000001f) + (x >>16 & 0x0000001f0000001f); + x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f); - x = (x & 0x000000000000003f) + (x >>32 & 0x000000000000003f); + x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f); ``` IIUC, this is a modified [hamming weight](https://en.wikipedia.org/wiki/Hamming_weight) based on [this SO answer](https://stackoverflow.com/a/73300535), so both implementations give the same result, but it's a bit confusing at first look, so I flagged it as `Misc` instead of `Bug`. -- https://bugs.ruby-lang.org/
Issue #21690 has been updated by nobu (Nobuyoshi Nakada). https://github.com/ruby/ruby/pull/15496 ---------------------------------------- Misc #21690: Inconsistent `rb_popcount64()` definition https://bugs.ruby-lang.org/issues/21690#change-115588 * Author: daniel.domjan (Dániel Domján) * Status: Open ---------------------------------------- The `rb_popcount64()` function is defined both in `internal/bits.h` and `parser_bits.h`, but the definition of these functions is different on the `#else` branch. ```c // internal/bits.h static inline unsigned int rb_popcount64(uint64_t x) { ... #else x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555); x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333); x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707); x = (x & 0x000f000f000f000f) + (x >> 8 & 0x000f000f000f000f); x = (x & 0x0000001f0000001f) + (x >>16 & 0x0000001f0000001f); x = (x & 0x000000000000003f) + (x >>32 & 0x000000000000003f); return (unsigned int)x; #endif } ``` ```c // parser_bits.h static inline unsigned int rb_popcount64(uint64_t x) { ... #else x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555); x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333); x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707); x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f); x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f); x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f); return (unsigned int)x; #endif } ``` ```diff x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555); x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333); x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707); - x = (x & 0x000f000f000f000f) + (x >> 8 & 0x000f000f000f000f); + x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f); - x = (x & 0x0000001f0000001f) + (x >>16 & 0x0000001f0000001f); + x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f); - x = (x & 0x000000000000003f) + (x >>32 & 0x000000000000003f); + x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f); ``` IIUC, this is a modified [hamming weight](https://en.wikipedia.org/wiki/Hamming_weight) based on [this SO answer](https://stackoverflow.com/a/73300535), so both implementations give the same result, but it's a bit confusing at first look, so I flagged it as `Misc` instead of `Bug`. -- https://bugs.ruby-lang.org/
participants (2)
-
daniel.domjan -
nobu (Nobuyoshi Nakada)