General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.4 KiB

  1. #pragma once
  2. #include "gp_config.hpp"
  3. #include "gp/algorithms/repeat.hpp"
  4. namespace gp {
  5. template<typename T>
  6. T lerp(T input, T low, T high) {
  7. return low + (high - low) * input;
  8. }
  9. template<typename T>
  10. T lextrap(T input, T low, T high) {
  11. return (input - low) / (high - low);
  12. }
  13. template<typename T, size_t fixed_passes = 16>
  14. T fixed_sqrt(T value) {
  15. gp_config::assertion(value >= 0, "trying to compute square root of negative number");
  16. if(value == 0) return 0;
  17. T ret = value / 2;
  18. T tmp;
  19. gp::repeat(fixed_passes, [&](){
  20. tmp = ret;
  21. ret = (value / tmp + tmp) / 2;
  22. });
  23. return ret;
  24. }
  25. template<typename T, size_t cap_passes = 16>
  26. T epsilon_sqrt(T value) {
  27. gp_config::assertion(value >= 0, "trying to compute square root of negative number");
  28. if(value == 0) return 0;
  29. T ret = value / 2;
  30. T tmp;
  31. constexpr T epsilon = gp_config::rendering::epsilon;
  32. size_t cnt = 0;
  33. while(
  34. !(
  35. (ret+epsilon)*ret > value
  36. && (ret-epsilon)*ret < value
  37. )
  38. && cnt < cap_passes
  39. ){
  40. tmp = ret;
  41. ret = (value / tmp + tmp) / 2;
  42. ++cnt;
  43. };
  44. return ret;
  45. }
  46. template<typename T, size_t cap_passes = 16>
  47. T stable_sqrt(T value) {
  48. gp_config::assertion(value >= 0, "trying to compute square root of negative number");
  49. if(value == 0) return 0;
  50. T ret = value / 2;
  51. T tmp;
  52. while(ret != tmp){
  53. tmp = ret;
  54. ret = (value / tmp + tmp) / 2;
  55. };
  56. return ret;
  57. }
  58. }