source: trunk/src/lol/math/real.h @ 2105

Last change on this file since 2105 was 2105, checked in by sam, 7 years ago

core: implement hashing functions for half, float and double.

  • Property svn:keywords set to Id
File size: 10.0 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11//
12// The Real class
13// --------------
14//
15
16#if !defined __LOL_MATH_REAL_H__
17#define __LOL_MATH_REAL_H__
18
19#include <stdint.h>
20
21namespace lol
22{
23
24/* This is OUR namespace. Don't let Windows headers fuck with it. */
25#undef min
26#undef max
27
28/* Avoid issues with NaCl headers */
29#undef log2
30
31/*
32 * The base class for reals. The only real reason for making this a template
33 * class is so we can have implicit constructors ("real x = 1" works) but
34 * avoid accidental implicit conversions ("int x = 1; sqrt(x)" will never
35 * call real::sqrt).
36 */
37template<int N> class Real
38{
39public:
40    Real();
41    Real(Real<N> const &x);
42    Real const &operator =(Real<N> const &x);
43    ~Real();
44
45    Real(float f);
46    Real(double f);
47    Real(int i);
48    Real(unsigned int i);
49
50    Real(char const *str);
51
52    operator float() const;
53    operator double() const;
54    operator int() const;
55    operator unsigned int() const;
56
57    Real<N> operator +() const;
58    Real<N> operator -() const;
59    Real<N> operator +(Real<N> const &x) const;
60    Real<N> operator -(Real<N> const &x) const;
61    Real<N> operator *(Real<N> const &x) const;
62    Real<N> operator /(Real<N> const &x) const;
63    Real<N> const &operator +=(Real<N> const &x);
64    Real<N> const &operator -=(Real<N> const &x);
65    Real<N> const &operator *=(Real<N> const &x);
66    Real<N> const &operator /=(Real<N> const &x);
67
68    bool operator ==(Real<N> const &x) const;
69    bool operator !=(Real<N> const &x) const;
70    bool operator <(Real<N> const &x) const;
71    bool operator >(Real<N> const &x) const;
72    bool operator <=(Real<N> const &x) const;
73    bool operator >=(Real<N> const &x) const;
74
75    bool operator !() const;
76    operator bool() const;
77
78    /* Comparison functions */
79    template<int M> friend Real<M> min(Real<M> const &a, Real<M> const &b);
80    template<int M> friend Real<M> max(Real<M> const &a, Real<M> const &b);
81    template<int M> friend Real<M> clamp(Real<M> const &x,
82                                         Real<M> const &a, Real<M> const &b);
83
84    /* Trigonometric functions */
85    template<int M> friend Real<M> sin(Real<M> const &x);
86    template<int M> friend Real<M> cos(Real<M> const &x);
87    template<int M> friend Real<M> tan(Real<M> const &x);
88    template<int M> friend Real<M> asin(Real<M> const &x);
89    template<int M> friend Real<M> acos(Real<M> const &x);
90    template<int M> friend Real<M> atan(Real<M> const &x);
91    template<int M> friend Real<M> atan2(Real<M> const &y, Real<M> const &x);
92
93    /* Hyperbolic functions */
94    template<int M> friend Real<M> sinh(Real<M> const &x);
95    template<int M> friend Real<M> cosh(Real<M> const &x);
96    template<int M> friend Real<M> tanh(Real<M> const &x);
97
98    /* Exponential and logarithmic functions */
99    template<int M> friend Real<M> exp(Real<M> const &x);
100    template<int M> friend Real<M> exp2(Real<M> const &x);
101    template<int M> friend Real<M> log(Real<M> const &x);
102    template<int M> friend Real<M> log2(Real<M> const &x);
103    template<int M> friend Real<M> log10(Real<M> const &x);
104    template<int M> friend Real<M> frexp(Real<M> const &x, int *exp);
105    template<int M> friend Real<M> ldexp(Real<M> const &x, int exp);
106    template<int M> friend Real<M> modf(Real<M> const &x, Real<M> *iptr);
107    template<int M> friend Real<M> ulp(Real<M> const &x);
108    template<int M> friend Real<M> nextafter(Real<M> const &x, Real<M> const &y);
109
110    /* Power functions */
111    template<int M> friend Real<M> re(Real<M> const &x);
112    template<int M> friend Real<M> sqrt(Real<M> const &x);
113    template<int M> friend Real<M> cbrt(Real<M> const &x);
114    template<int M> friend Real<M> pow(Real<M> const &x, Real<M> const &y);
115    template<int M> friend Real<M> gamma(Real<M> const &x);
116
117    /* Rounding, absolute value, remainder etc. */
118    template<int M> friend Real<M> ceil(Real<M> const &x);
119    template<int M> friend Real<M> copysign(Real<M> const &x, Real<M> const &y);
120    template<int M> friend Real<M> floor(Real<M> const &x);
121    template<int M> friend Real<M> fabs(Real<M> const &x);
122    template<int M> friend Real<M> round(Real<M> const &x);
123    template<int M> friend Real<M> fmod(Real<M> const &x, Real<N> const &y);
124
125    void hexprint() const;
126    void print(int ndigits = 150) const;
127    void sprintf(char *str, int ndigits = 150) const;
128
129    /* Additional operators using base C++ types */
130#define __LOL_REAL_OP_HELPER_GENERIC(op, type) \
131    inline Real<N> operator op(type x) const { return *this op (Real<N>)x; } \
132    inline Real<N> const &operator op##=(type x) { return *this = (*this op x); }
133#define __LOL_REAL_OP_HELPER_FASTMULDIV(op, type) \
134    inline Real<N> operator op(type x) const \
135    { \
136        Real<N> tmp = *this; return tmp op##= x; \
137    } \
138    inline Real<N> const &operator op##=(type x) \
139    { \
140        /* If multiplying or dividing by a power of two, take a shortcut */ \
141        if ((m_signexp << 1) && x && !(x & (x - 1))) \
142        { \
143            while (x >>= 1) \
144                m_signexp += 1 op 2 - 1; /* 1 if op is *, -1 if op is / */ \
145        } \
146        else \
147            *this = *this op (Real<N>)x; \
148        return *this; \
149    }
150#define __LOL_REAL_OP_HELPER_INT(type) \
151    __LOL_REAL_OP_HELPER_GENERIC(+, type) \
152    __LOL_REAL_OP_HELPER_GENERIC(-, type) \
153    __LOL_REAL_OP_HELPER_FASTMULDIV(*, type) \
154    __LOL_REAL_OP_HELPER_FASTMULDIV(/, type)
155#define __LOL_REAL_OP_HELPER_FLOAT(type) \
156    __LOL_REAL_OP_HELPER_GENERIC(+, type) \
157    __LOL_REAL_OP_HELPER_GENERIC(-, type) \
158    __LOL_REAL_OP_HELPER_GENERIC(*, type) \
159    __LOL_REAL_OP_HELPER_GENERIC(/, type)
160
161    __LOL_REAL_OP_HELPER_INT(int)
162    __LOL_REAL_OP_HELPER_INT(unsigned int)
163    __LOL_REAL_OP_HELPER_FLOAT(float)
164    __LOL_REAL_OP_HELPER_FLOAT(double)
165
166    /* Constants */
167    static Real<N> const& R_0();
168    static Real<N> const& R_1();
169    static Real<N> const& R_2();
170    static Real<N> const& R_3();
171    static Real<N> const& R_4();
172    static Real<N> const& R_10();
173
174    static Real<N> const& R_E();
175    static Real<N> const& R_LOG2E();
176    static Real<N> const& R_LOG10E();
177    static Real<N> const& R_LN2();
178    static Real<N> const& R_LN10();
179    static Real<N> const& R_PI();
180    static Real<N> const& R_PI_2();
181    static Real<N> const& R_PI_3();
182    static Real<N> const& R_PI_4();
183    static Real<N> const& R_1_PI();
184    static Real<N> const& R_2_PI();
185    static Real<N> const& R_2_SQRTPI();
186    static Real<N> const& R_SQRT2();
187    static Real<N> const& R_SQRT3();
188    static Real<N> const& R_SQRT1_2();
189
190    /* XXX: changing this requires tuning real::fres (the number of
191     * Newton-Raphson iterations) and real::print (the number of printed
192     * digits) */
193    static int const BIGITS = N;
194    static int const BIGIT_BITS = 32;
195
196private:
197    uint32_t *m_mantissa;
198    uint32_t m_signexp;
199};
200
201/*
202 * Mandatory forward declarations of template specialisations
203 */
204template<> real::Real();
205template<> real::Real(real const &x);
206template<> real const &real::operator =(real const &x);
207template<> real::~Real();
208template<> real::Real(float f);
209template<> real::Real(double f);
210template<> real::Real(int i);
211template<> real::Real(unsigned int i);
212template<> real::Real(char const *str);
213
214template<> real::operator float() const;
215template<> real::operator double() const;
216template<> real::operator int() const;
217template<> real::operator unsigned int() const;
218template<> real real::operator +() const;
219template<> real real::operator -() const;
220template<> real real::operator +(real const &x) const;
221template<> real real::operator -(real const &x) const;
222template<> real real::operator *(real const &x) const;
223template<> real real::operator /(real const &x) const;
224template<> real const &real::operator +=(real const &x);
225template<> real const &real::operator -=(real const &x);
226template<> real const &real::operator *=(real const &x);
227template<> real const &real::operator /=(real const &x);
228template<> bool real::operator ==(real const &x) const;
229template<> bool real::operator !=(real const &x) const;
230template<> bool real::operator <(real const &x) const;
231template<> bool real::operator >(real const &x) const;
232template<> bool real::operator <=(real const &x) const;
233template<> bool real::operator >=(real const &x) const;
234template<> bool real::operator !() const;
235template<> real::operator bool() const;
236
237template<> real min(real const &a, real const &b);
238template<> real max(real const &a, real const &b);
239template<> real clamp(real const &x, real const &a, real const &b);
240
241template<> real sin(real const &x);
242template<> real cos(real const &x);
243template<> real tan(real const &x);
244template<> real asin(real const &x);
245template<> real acos(real const &x);
246template<> real atan(real const &x);
247template<> real atan2(real const &y, real const &x);
248template<> real sinh(real const &x);
249template<> real cosh(real const &x);
250template<> real tanh(real const &x);
251template<> real exp(real const &x);
252template<> real exp2(real const &x);
253template<> real log(real const &x);
254template<> real log2(real const &x);
255template<> real log10(real const &x);
256template<> real frexp(real const &x, int *exp);
257template<> real ldexp(real const &x, int exp);
258template<> real modf(real const &x, real *iptr);
259template<> real ulp(real const &x);
260template<> real nextafter(real const &x, real const &y);
261template<> real re(real const &x);
262template<> real sqrt(real const &x);
263template<> real cbrt(real const &x);
264template<> real pow(real const &x, real const &y);
265template<> real gamma(real const &x);
266template<> real ceil(real const &x);
267template<> real copysign(real const &x, real const &y);
268template<> real floor(real const &x);
269template<> real fabs(real const &x);
270template<> real round(real const &x);
271template<> real fmod(real const &x, real const &y);
272
273template<> void real::hexprint() const;
274template<> void real::print(int ndigits) const;
275
276} /* namespace lol */
277
278#endif // __LOL_MATH_REAL_H__
279
Note: See TracBrowser for help on using the repository browser.