diff --git a/src/lol/math/half.h b/src/lol/math/half.h index d47158aa..fc543ad8 100644 --- a/src/lol/math/half.h +++ b/src/lol/math/half.h @@ -120,7 +120,11 @@ public: static inline half min(half a, half b) { return a < b ? a : b; } static inline half max(half a, half b) { return a > b ? a : b; } -static inline half fmod(half a, half b) { return (half)fmod((float)a, (float)b); } +static inline half fmod(half a, half b) +{ + using std::fmod; + return (half)fmod((float)a, (float)b); +} static inline half abs(half a) { return half::makebits(a.bits & 0x7fffu); } static inline half clamp(half x, half a, half b) diff --git a/src/lol/math/math.h b/src/lol/math/math.h index 6d156000..cd046b8d 100644 --- a/src/lol/math/math.h +++ b/src/lol/math/math.h @@ -18,11 +18,23 @@ #include #include +#include + #include namespace lol { +/* This is OUR namespace. Don't let Windows headers fuck with it. */ +#undef min +#undef max + +/* There are many reasons for wanting single-word type names, the most + * important one being compilation speedups in our vector.h: we can hide + * some global methods in namespaces that contain the name of the type, + * but namespaces cannot have spaces in their names. */ +typedef long double ldouble; + /* Standard cmath functions */ static inline double sqrt(double const &x) { return std::sqrt(x); } static inline float sqrt(float const &x) { return std::sqrt(x); } @@ -64,11 +76,17 @@ static inline void sincos(float const &x, float *s, float *c) *c = std::cos(x); } +static inline float lerp(float const &a, float const &b, float const &x) +{ + return a + (b - a) * x; +} + static inline double lerp(double const &a, double const &b, double const &x) { return a + (b - a) * x; } -static inline float lerp(float const &a, float const &b, float const &x) + +static inline ldouble lerp(ldouble const &a, ldouble const &b, ldouble const &x) { return a + (b - a) * x; } @@ -85,6 +103,56 @@ double lol_acos(double); double lol_atan(double); double lol_atan2(double, double); +/* C++ doesn't define abs() and fmod() for all types; we add these for + * convenience to avoid adding complexity to vector.h. */ +static inline int8_t abs(int8_t x) { return std::abs(x); } +static inline uint8_t abs(uint8_t x) { return x; } +static inline int16_t abs(int16_t x) { return std::abs(x); } +static inline uint16_t abs(uint16_t x) { return x; } +static inline int32_t abs(int32_t x) { return std::abs(x); } +static inline uint32_t abs(uint32_t x) { return x; } +static inline int64_t abs(int64_t x) { return std::abs(x); } +static inline uint64_t abs(uint64_t x) { return x; } +static inline float abs(float x) { return std::abs(x); } +static inline double abs(double x) { return std::abs(x); } +static inline ldouble abs(ldouble x) { return std::abs(x); } + +static inline uint8_t fmod(uint8_t x, uint8_t y) { return x % y; } +static inline int8_t fmod(int8_t x, int8_t y) { return x % y; } +static inline uint16_t fmod(uint16_t x, uint16_t y) { return x % y; } +static inline int16_t fmod(int16_t x, int16_t y) { return x % y; } +static inline uint32_t fmod(uint32_t x, uint32_t y) { return x % y; } +static inline int32_t fmod(int32_t x, int32_t y) { return x % y; } +static inline uint64_t fmod(uint64_t x, uint64_t y) { return x % y; } +static inline int64_t fmod(int64_t x, int64_t y) { return x % y; } +static inline float fmod(float x, float y) { return std::fmod(x, y); } +static inline double fmod(double x, double y) { return std::fmod(x, y); } +static inline ldouble fmod(ldouble x, ldouble y) { return std::fmod(x, y); } + +static inline uint8_t min(uint8_t x, uint8_t y) { return std::min(x, y); } +static inline int8_t min(int8_t x, int8_t y) { return std::min(x, y); } +static inline uint16_t min(uint16_t x, uint16_t y) { return std::min(x, y); } +static inline int16_t min(int16_t x, int16_t y) { return std::min(x, y); } +static inline uint32_t min(uint32_t x, uint32_t y) { return std::min(x, y); } +static inline int32_t min(int32_t x, int32_t y) { return std::min(x, y); } +static inline uint64_t min(uint64_t x, uint64_t y) { return std::min(x, y); } +static inline int64_t min(int64_t x, int64_t y) { return std::min(x, y); } +static inline float min(float x, float y) { return std::min(x, y); } +static inline double min(double x, double y) { return std::min(x, y); } +static inline ldouble min(ldouble x, ldouble y) { return std::min(x, y); } + +static inline uint8_t max(uint8_t x, uint8_t y) { return std::max(x, y); } +static inline int8_t max(int8_t x, int8_t y) { return std::max(x, y); } +static inline uint16_t max(uint16_t x, uint16_t y) { return std::max(x, y); } +static inline int16_t max(int16_t x, int16_t y) { return std::max(x, y); } +static inline uint32_t max(uint32_t x, uint32_t y) { return std::max(x, y); } +static inline int32_t max(int32_t x, int32_t y) { return std::max(x, y); } +static inline uint64_t max(uint64_t x, uint64_t y) { return std::max(x, y); } +static inline int64_t max(int64_t x, int64_t y) { return std::max(x, y); } +static inline float max(float x, float y) { return std::max(x, y); } +static inline double max(double x, double y) { return std::max(x, y); } +static inline ldouble max(ldouble x, ldouble y) { return std::max(x, y); } + } /* namespace lol */ #endif // __LOL_MATH_MATH_H__ diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index 93cb9e4e..36ce63f8 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -18,7 +18,6 @@ #include #include -#include #include "lol/math/math.h" #include "lol/math/half.h" @@ -27,10 +26,6 @@ namespace lol { -/* This is OUR namespace. Don't let Windows headers fuck with it. */ -#undef min -#undef max - /* Some compilers do not support const members in anonymous unions. So * far, GCC (>= 4.6), CLang (3.0) and Visual Studio (>= 2010) appear to * work properly. */ @@ -39,16 +34,12 @@ namespace lol # define LOL_NO_CONST_MEMBERS_IN_ANONYMOUS_UNIONS 1 #endif -/* Hack for compilation speedups: we can hide some of our global methods in - * namespaces. We therefore want "long_double" to be a single-word name */ -typedef long double long_double; - #define DECLARE_VECTOR_TYPEDEFS(tname, suffix) \ template struct tname; \ typedef tname f16##suffix; \ typedef tname suffix; \ typedef tname d##suffix; \ - typedef tname f128##suffix; \ + typedef tname f128##suffix; \ typedef tname i8##suffix; \ typedef tname u8##suffix; \ typedef tname i16##suffix; \ @@ -1073,7 +1064,7 @@ extern Quat slerp(Quat const &qa, Quat const &qb, T f); tprefix \ inline tname op(tname const &a, tname const &b) \ { \ - using std::op; \ + using lol::op; \ tname ret; \ for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ ret[n] = op(a[n], b[n]); \ @@ -1083,7 +1074,7 @@ extern Quat slerp(Quat const &qa, Quat const &qb, T f); tprefix \ inline tname op(tname const &a, type const &b) \ { \ - using std::op; \ + using lol::op; \ tname ret; \ for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ ret[n] = op(a[n], b); \ @@ -1093,7 +1084,7 @@ extern Quat slerp(Quat const &qa, Quat const &qb, T f); tprefix \ inline tname op(type const &a, tname const &b) \ { \ - using std::op; \ + using lol::op; \ tname ret; \ for (size_t n = 0; n < sizeof(b) / sizeof(type); n++) \ ret[n] = op(a, b[n]); \ @@ -1227,10 +1218,9 @@ extern Quat slerp(Quat const &qa, Quat const &qb, T f); tprefix \ inline tname abs(tname const &a) \ { \ - using std::abs; \ tname ret; \ for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = abs(a[n]); \ + ret[n] = lol::abs(a[n]); \ return ret; \ } @@ -1360,7 +1350,7 @@ DECLARE_ALL_NONVECTOR_OPS(Quat) DECLARE_ALL_VECTOR_OPS(half) DECLARE_ALL_VECTOR_OPS(float) DECLARE_ALL_VECTOR_OPS(double) -DECLARE_ALL_VECTOR_OPS(long_double) +DECLARE_ALL_VECTOR_OPS(ldouble) DECLARE_ALL_VECTOR_OPS(int8_t) DECLARE_ALL_VECTOR_OPS(uint8_t) DECLARE_ALL_VECTOR_OPS(int16_t) @@ -1401,7 +1391,7 @@ DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, int64_t) DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, uint64_t) DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, float) DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, double) -DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(int8_t, ldouble) DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, int16_t) DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, uint16_t) @@ -1411,7 +1401,7 @@ DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, int64_t) DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, uint64_t) DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, float) DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, double) -DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(uint8_t, ldouble) DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, uint16_t) DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, int32_t) @@ -1420,7 +1410,7 @@ DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, int64_t) DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, uint64_t) DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, float) DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, double) -DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(int16_t, ldouble) DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, int32_t) DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, uint32_t) @@ -1428,34 +1418,34 @@ DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, int64_t) DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, uint64_t) DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, float) DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, double) -DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(uint16_t, ldouble) DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, uint32_t) DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, int64_t) DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, uint64_t) DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, float) DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, double) -DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(int32_t, ldouble) DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, int64_t) DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, uint64_t) DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, float) DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, double) -DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(uint32_t, ldouble) DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, uint64_t) DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, float) DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, double) -DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(int64_t, ldouble) DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, float) DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, double) -DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, ldouble) DECLARE_ALL_VECTOR_COERCE_OPS(float, double) -DECLARE_ALL_VECTOR_COERCE_OPS(float, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(float, ldouble) -DECLARE_ALL_VECTOR_COERCE_OPS(double, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(double, ldouble) /* FIXME: vectors of "half" are deactivated for now, because they * induce extremely long compilation times (about 17 seconds per TU). */ @@ -1474,7 +1464,7 @@ DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, half) DECLARE_ALL_VECTOR_COERCE_OPS(half, float) DECLARE_ALL_VECTOR_COERCE_OPS(half, double) -DECLARE_ALL_VECTOR_COERCE_OPS(half, long_double) +DECLARE_ALL_VECTOR_COERCE_OPS(half, ldouble) #endif /* FIXME: vectors of "real" are deactivated for now, because we do @@ -1493,7 +1483,7 @@ DECLARE_ALL_VECTOR_COERCE_OPS(uint64_t, real) DECLARE_ALL_VECTOR_COERCE_OPS(half, real) DECLARE_ALL_VECTOR_COERCE_OPS(float, real) DECLARE_ALL_VECTOR_COERCE_OPS(double, real) -DECLARE_ALL_VECTOR_COERCE_OPS(long_double, real) +DECLARE_ALL_VECTOR_COERCE_OPS(ldouble, real) #endif /* Activate all the namespaces that we created. Delaying this activation @@ -1518,7 +1508,7 @@ DECLARE_ALL_VECTOR_COERCE_OPS(long_double, real) ACTIVATE_COERCE_NAMESPACES_INNER(tlow, half) \ ACTIVATE_COERCE_NAMESPACES_INNER(tlow, float) \ ACTIVATE_COERCE_NAMESPACES_INNER(tlow, double) \ - ACTIVATE_COERCE_NAMESPACES_INNER(tlow, long_double) \ + ACTIVATE_COERCE_NAMESPACES_INNER(tlow, ldouble) \ ACTIVATE_COERCE_NAMESPACES_INNER(tlow, real) ACTIVATE_COERCE_NAMESPACES(int8_t) @@ -1532,7 +1522,7 @@ ACTIVATE_COERCE_NAMESPACES(uint64_t) ACTIVATE_COERCE_NAMESPACES(half) ACTIVATE_COERCE_NAMESPACES(float) ACTIVATE_COERCE_NAMESPACES(double) -ACTIVATE_COERCE_NAMESPACES(long_double) +ACTIVATE_COERCE_NAMESPACES(ldouble) ACTIVATE_COERCE_NAMESPACES(real) #if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) diff --git a/test/math/poly.cpp b/test/math/poly.cpp index 9f9d1e76..5920c9e6 100644 --- a/test/math/poly.cpp +++ b/test/math/poly.cpp @@ -123,7 +123,7 @@ printf("-- START --\n"); { union { float f; uint32_t x; } s1 = { sinf(adjustf(u.f, 0)) }; union { float f; uint32_t x; } s2 = { floatsin(adjustf(u.f, 0)) }; - int e = abs((int)(s1.x - s2.x)); + int e = lol::abs((int)(s1.x - s2.x)); switch (e) { case 3: @@ -132,7 +132,7 @@ printf("-- START --\n"); inspect(u.f); printf("sinf: "); inspect(sinf(u.f)); - if (fabs((double)s1.f - (double)s2.f) > 1e-10 * fabs(s1.f)) + if (lol::abs((double)s1.f - (double)s2.f) > 1e-10 * lol::abs(s1.f)) printf("%15.13g %08x: %15.13g %15.13g %08x %08x\n", u.f, u.x, s1.f, s2.f, s1.x, s2.x); case 0: error[e]++; diff --git a/tutorial/11_fractal.cpp b/tutorial/11_fractal.cpp index 7fd16a01..de506867 100644 --- a/tutorial/11_fractal.cpp +++ b/tutorial/11_fractal.cpp @@ -215,7 +215,7 @@ public: else if (m_zoom_speed) { m_zoom_speed *= std::pow(2.0, -seconds * 5.0); - if (abs(m_zoom_speed) < 1e-5 || m_drag) + if (lol::abs(m_zoom_speed) < 1e-5 || m_drag) m_zoom_speed = 0.0; } #endif