| 1720 | |
| 1721 | template <typename T> |
| 1722 | AccuracyResult measure_atan2_t() { |
| 1723 | AccuracyResult r = {}; |
| 1724 | const int N = 5; // Spot testing: 5×5 = 25 samples (was 20×20 = 400) |
| 1725 | constexpr int intBits = T::INT_BITS; |
| 1726 | const float maxRange = static_cast<float>((1 << (intBits - 1)) - 1); |
| 1727 | const float lo = -(maxRange < 7.0f ? maxRange : 7.0f); |
| 1728 | const float hi = (maxRange < 7.0f ? maxRange : 7.0f); |
| 1729 | float sumErr = 0; |
| 1730 | int count = 0; |
| 1731 | for (int ix = 0; ix < N; ++ix) { |
| 1732 | for (int iy = 0; iy < N; ++iy) { |
| 1733 | float x = lo + (hi - lo) * ix / (N - 1); |
| 1734 | float y = lo + (hi - lo) * iy / (N - 1); |
| 1735 | if (fl::fabsf(x) < 0.01f && fl::fabsf(y) < 0.01f) continue; |
| 1736 | float ref = fl::atan2f(y, x); |
| 1737 | float got = T::atan2(T(y), T(x)).to_float(); |
| 1738 | float err = fl::fabsf(got - ref); |
| 1739 | sumErr += err; |
| 1740 | ++count; |
| 1741 | if (err > r.maxErr) { r.maxErr = err; r.worstInput = y; r.worstInput2 = x; } |
| 1742 | } |
| 1743 | } |
| 1744 | r.avgErr = count > 0 ? sumErr / count : 0; |
| 1745 | r.nSamples = count; |
| 1746 | return r; |
| 1747 | } |
| 1748 | |
| 1749 | template <typename T> |
| 1750 | AccuracyResult measure_asin_t() { |