barrett.hpp 716 B

1234567891011121314151617181920212223242526272829
  1. #pragma once
  2. namespace nall {
  3. template<uint Bits> struct BarrettReduction {
  4. using type = typename ArithmeticNatural<1 * Bits>::type;
  5. using pair = typename ArithmeticNatural<2 * Bits>::type;
  6. explicit BarrettReduction(type modulo) : modulo(modulo), factor(pair(1) + -pair(modulo) / modulo) {}
  7. //return => value % modulo
  8. auto operator()(pair value) const -> type {
  9. pair hi, lo;
  10. mul(value, factor, hi, lo);
  11. pair remainder = value - hi * modulo;
  12. return remainder < modulo ? remainder : remainder - modulo;
  13. }
  14. private:
  15. const pair modulo;
  16. const pair factor;
  17. };
  18. template<typename T, uint Bits> auto operator%(T value, const BarrettReduction<Bits>& modulo) {
  19. return modulo(value);
  20. }
  21. }