PolyfloatUtil.h 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #ifndef MANDEL_POLYFLOATUTIL_H
  2. #define MANDEL_POLYFLOATUTIL_H
  3. namespace mnd
  4. {
  5. namespace pfu
  6. {
  7. template<typename T>
  8. struct Pair
  9. {
  10. T a;
  11. T b;
  12. };
  13. using DoublePair = Pair<double>;
  14. using FloatPair = Pair<float>;
  15. template<typename T>
  16. inline static Pair<T> quickTwoSum(T a, T b)
  17. {
  18. T s = a + b;
  19. T e = b - (s - a);
  20. return { s, e };
  21. }
  22. template<typename T>
  23. inline Pair<T> twoSum(T a, T b)
  24. {
  25. T s = a + b;
  26. T v = s - a;
  27. T e = (a - (s - v)) + (b - v);
  28. return { s, e };
  29. }
  30. template<typename T>
  31. inline Pair<T> threeTwoSum(T a, T b, T c)
  32. {
  33. auto[t1, t2] = twoSum(a, b);
  34. auto[r0, t3] = twoSum(t1, c);
  35. return { r0, t2 + t3 };
  36. }
  37. inline Pair<double> split(double a)
  38. {
  39. static const double splitter = double((1ULL << 27) + 1);
  40. double t = splitter * a;
  41. double ahi = t - (t - a);
  42. double alo = a - ahi;
  43. return { ahi, alo };
  44. }
  45. template<typename T>
  46. inline Pair<T> twoProd(T a, T b)
  47. {
  48. T p = a * b;
  49. auto [ahi, alo] = split(a);
  50. auto [bhi, blo] = split(b);
  51. T e = ((ahi * bhi - p) + ahi * blo + alo * bhi) + alo * blo;
  52. return { p, e };
  53. }
  54. template<typename T>
  55. inline Pair<T> twoProdFma(T a, T b)
  56. {
  57. T p = a * b;
  58. //T e = std::fma(a, b, -p);
  59. T e = 0;
  60. return { p, e };
  61. }
  62. }
  63. }
  64. #endif // MANDEL_POLYFLOATUTIL_H