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

Last change on this file since 1130 was 1130, checked in by sam, 10 years ago

math: implement ulp() for reals, which returns the smallest real y > 0 such
that x + y != x, and nextafter() which behaves like the C function.

  • Property svn:keywords set to Id
File size: 5.4 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
21/* Avoid issues with NaCl headers */
22#undef log2
23
24namespace lol
25{
26
27class real
28{
29public:
30    real();
31    real(real const &x);
32    real const &operator =(real const &x);
33    ~real();
34
35    real(float f);
36    real(double f);
37    real(int i);
38    real(unsigned int i);
39
40    real(char const *str);
41
42    operator float() const;
43    operator double() const;
44    operator int() const;
45    operator unsigned int() const;
46
47    real operator +() const;
48    real operator -() const;
49    real operator +(real const &x) const;
50    real operator -(real const &x) const;
51    real operator *(real const &x) const;
52    real operator /(real const &x) const;
53    real const &operator +=(real const &x);
54    real const &operator -=(real const &x);
55    real const &operator *=(real const &x);
56    real const &operator /=(real const &x);
57
58    bool operator ==(real const &x) const;
59    bool operator !=(real const &x) const;
60    bool operator <(real const &x) const;
61    bool operator >(real const &x) const;
62    bool operator <=(real const &x) const;
63    bool operator >=(real const &x) const;
64
65    bool operator !() const;
66    operator bool() const;
67
68    /* Trigonometric functions */
69    friend real sin(real const &x);
70    friend real cos(real const &x);
71    friend real tan(real const &x);
72    friend real asin(real const &x);
73    friend real acos(real const &x);
74    friend real atan(real const &x);
75    friend real atan2(real const &y, real const &x);
76
77    /* Hyperbolic functions */
78    friend real sinh(real const &x);
79    friend real cosh(real const &x);
80    friend real tanh(real const &x);
81
82    /* Exponential and logarithmic functions */
83    friend real exp(real const &x);
84    friend real exp2(real const &x);
85    friend real log(real const &x);
86    friend real log2(real const &x);
87    friend real log10(real const &x);
88    friend real frexp(real const &x, int *exp);
89    friend real ldexp(real const &x, int exp);
90    friend real modf(real const &x, real *iptr);
91    friend real ulp(real const &x);
92    friend real nextafter(real const &x, real const &y);
93
94    /* Power functions */
95    friend real re(real const &x);
96    friend real sqrt(real const &x);
97    friend real cbrt(real const &x);
98    friend real pow(real const &x, real const &y);
99    friend real gamma(real const &x);
100
101    /* Rounding, absolute value, remainder etc. */
102    friend real ceil(real const &x);
103    friend real copysign(real const &x, real const &y);
104    friend real floor(real const &x);
105    friend real fabs(real const &x);
106    friend real round(real const &x);
107    friend real fmod(real const &x, real const &y);
108
109    void hexprint() const;
110    void print(int ndigits = 150) const;
111
112    /* Additional operators using base C++ types */
113#define __LOL_REAL_OP_HELPER_GENERIC(op, type) \
114    inline real operator op(type x) const { return *this op (real)x; } \
115    inline real const &operator op##=(type x) { return *this = (*this op x); }
116#define __LOL_REAL_OP_HELPER_FASTMULDIV(op, type) \
117    inline real operator op(type x) const \
118    { \
119        real tmp = *this; return tmp op##= x; \
120    } \
121    inline real const &operator op##=(type x) \
122    { \
123        /* If multiplying or dividing by a power of two, take a shortcut */ \
124        if ((m_signexp << 1) && x && !(x & (x - 1))) \
125        { \
126            while (x >>= 1) \
127                m_signexp += 1 op 2 - 1; /* 1 if op is *, -1 if op is / */ \
128        } \
129        else \
130            *this = *this op (real)x; \
131        return *this; \
132    }
133#define __LOL_REAL_OP_HELPER_INT(type) \
134    __LOL_REAL_OP_HELPER_GENERIC(+, type) \
135    __LOL_REAL_OP_HELPER_GENERIC(-, type) \
136    __LOL_REAL_OP_HELPER_FASTMULDIV(*, type) \
137    __LOL_REAL_OP_HELPER_FASTMULDIV(/, type)
138#define __LOL_REAL_OP_HELPER_FLOAT(type) \
139    __LOL_REAL_OP_HELPER_GENERIC(+, type) \
140    __LOL_REAL_OP_HELPER_GENERIC(-, type) \
141    __LOL_REAL_OP_HELPER_GENERIC(*, type) \
142    __LOL_REAL_OP_HELPER_GENERIC(/, type)
143
144    __LOL_REAL_OP_HELPER_INT(int)
145    __LOL_REAL_OP_HELPER_INT(unsigned int)
146    __LOL_REAL_OP_HELPER_FLOAT(float)
147    __LOL_REAL_OP_HELPER_FLOAT(double)
148
149    /* Constants */
150    static real const R_0;
151    static real const R_1;
152    static real const R_2;
153    static real const R_3;
154    static real const R_10;
155
156    static real const R_E;
157    static real const R_LOG2E;
158    static real const R_LOG10E;
159    static real const R_LN2;
160    static real const R_LN10;
161    static real const R_PI;
162    static real const R_PI_2;
163    static real const R_PI_3;
164    static real const R_PI_4;
165    static real const R_1_PI;
166    static real const R_2_PI;
167    static real const R_2_SQRTPI;
168    static real const R_SQRT2;
169    static real const R_SQRT3;
170    static real const R_SQRT1_2;
171
172    /* XXX: changing this requires tuning real::fres (the number of
173     * Newton-Raphson iterations) and real::print (the number of printed
174     * digits) */
175    static int const BIGITS = 16;
176    static int const BIGIT_BITS = 32;
177
178private:
179    uint32_t *m_mantissa;
180    uint32_t m_signexp;
181};
182
183} /* namespace lol */
184
185#endif // __LOL_MATH_REAL_H__
186
Note: See TracBrowser for help on using the repository browser.