Code: Show/Hide #define MAPPING_ROUNDS 32 u16 map_freq_to_group(u16 n, u32 k) { for (u16 i = 0; i < MAPPING_ROUNDS; ++i) { /* mixed congruential method (Knuth, AoCP, 3.2.1) */ k = (65537 * 11 * k + 2099863) % 0xffffffff; n += k; n = (n << (k&15)) | (n >> (16 - (k&15))); } return n; } u16 _map_group_to_freq(u16 n, u32 k, u16 i) { k = (65537 * 11 * k + 2099863) % 0xffffffff; if (i) n = _map_group_to_freq(n, k, i-1); n = (n >> (k&15)) | (n << (16 - (k&15))); n -= k; return n; } u16 map_group_to_freq(u16 n, u32 k) { return _map_group_to_freq(n, k, MAPPING_ROUNDS-1); } |
Code: Show/Hide #define MAPPING_ROUNDS 32 u16 map_freq_to_group(u16 n, u32 k) { for (u16 i = 0; i < MAPPING_ROUNDS; ++i) { /* mixed congruential method (Knuth, AoCP, 3.2.1) */ k = (65537 * 11 * k + 2099863) % 0xffffffff; n += k; n = (n << (k%15)) | ((n&0x7fff) >> (15 - (k%15))); } return n | 0x8000; /* make it outside of range */ } u16 _map_group_to_freq(u16 n, u32 k, u16 i) { k = (65537 * 11 * k + 2099863) % 0xffffffff; if (i) n = _map_group_to_freq(n, k, i-1); n = ((n&0x7fff) >> (k%15)) | (n << (15 - (k%15))); n -= k; return n; } u16 map_group_to_freq(u16 n, u32 k) { return _map_group_to_freq(n, k, MAPPING_ROUNDS-1) & 0x7fff; } |