source: trunk/src/lol/math/half.h @ 1176

Last change on this file since 1176 was 1176, checked in by sam, 9 years ago

math: add vectors of "half" to vector.h.

  • Property svn:keywords set to Id
File size: 6.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 Half class
13// --------------
14//
15
16#if !defined __LOL_HALF_H__
17#define __LOL_HALF_H__
18
19#include <cstdio>
20#include <stdint.h>
21
22namespace lol
23{
24
25class half
26{
27public:
28    /* Constructors. Always inline so that the code can work in registers
29     * instead of calling routines with the hidden "this" parameter. */
30    inline half() { }
31    inline half(int f) { *this = makefast((float)f); }
32    inline half(float f) { *this = makefast(f); }
33    inline half(double f) { *this = makefast((float)f); }
34    inline half(long double f) { *this = makefast((float)f); }
35
36    inline int is_nan() const
37    {
38        return ((bits & 0x7c00u) == 0x7c00u) && (bits & 0x03ffu);
39    }
40
41    inline int is_finite() const
42    {
43        return (bits & 0x7c00u) != 0x7c00u;
44    }
45
46    inline int is_inf() const
47    {
48        return (uint16_t)(bits << 1) == (0x7c00u << 1);
49    }
50
51    inline int is_normal() const
52    {
53        return (is_finite() && (bits & 0x7c00u)) || ((bits & 0x7fffu) == 0);
54    }
55
56    /* Cast to other types -- always inline, see constructors */
57    inline half &operator =(int f) { return *this = makefast((float)f); }
58    inline half &operator =(float f) { return *this = makefast(f); }
59    inline half &operator =(double f) { return *this = makefast((float)f); }
60    inline half &operator =(long double f) { return *this = makefast((float)f); }
61    inline operator int8_t() const { return (int8_t)(float)*this; }
62    inline operator uint8_t() const { return (uint8_t)(float)*this; }
63    inline operator int16_t() const { return (int16_t)(float)*this; }
64    inline operator uint16_t() const { return (uint16_t)(float)*this; }
65    inline operator int32_t() const { return (int32_t)(float)*this; }
66    inline operator uint32_t() const { return (uint32_t)(float)*this; }
67    inline operator int64_t() const { return (int64_t)(float)*this; }
68    inline operator uint64_t() const { return (uint64_t)(float)*this; }
69
70    inline operator float() const { return tofloat(*this); }
71    inline operator double() const { return tofloat(*this); }
72    inline operator long double() const { return tofloat(*this); }
73
74    static float tofloat(half h);
75
76    /* Array conversions */
77    static size_t convert(half *dst, float const *src, size_t nelem);
78    static size_t convert(float *dst, half const *src, size_t nelem);
79
80    /* Operations */
81    bool operator ==(half x) const { return (float)*this == (float)x; }
82    bool operator !=(half x) const { return (float)*this != (float)x; }
83    bool operator <(half x) const { return (float)*this < (float)x; }
84    bool operator >(half x) const { return (float)*this > (float)x; }
85    bool operator <=(half x) const { return (float)*this <= (float)x; }
86    bool operator >=(half x) const { return (float)*this >= (float)x; }
87
88    bool operator !() const { return !(bits & 0x7fffu); }
89    operator bool() const { return !!*this; }
90
91    inline half operator -() const { return makebits(bits ^ 0x8000u); }
92    inline half operator +() const { return *this; }
93    inline half &operator +=(half h) { return (*this = (half)(*this + h)); }
94    inline half &operator -=(half h) { return (*this = (half)(*this - h)); }
95    inline half &operator *=(half h) { return (*this = (half)(*this * h)); }
96    inline half &operator /=(half h) { return (*this = (half)(*this / h)); }
97
98    inline float operator +(half h) const { return (float)*this + (float)h; }
99    inline float operator -(half h) const { return (float)*this - (float)h; }
100    inline float operator *(half h) const { return (float)*this * (float)h; }
101    inline float operator /(half h) const { return (float)*this / (float)h; }
102
103    /* Factories */
104    static half makefast(float f);
105    static half makeaccurate(float f);
106    static inline half makebits(uint16_t x)
107    {
108        half ret;
109        ret.bits = x;
110        return ret;
111    }
112
113    /* Internal representation */
114    uint16_t bits;
115};
116
117#define DECLARE_COERCE_HALF_NUMERIC_OPS(op, type, ret, x2, h2) \
118    inline ret operator op(type x, half h) { return x2 op h2; } \
119    inline ret operator op(half h, type x) { return h2 op x2; } \
120    inline type &operator op##=(type &x, half h) { return x = x op h2; } \
121    inline half &operator op##=(half &h, type x) { return h = h op x2; }
122
123#define DECLARE_COERCE_HALF_BOOL_OPS(op, type, x2, h2) \
124    inline bool operator op(type x, half h) { return x2 op h2; } \
125    inline bool operator op(half h, type x) { return h2 op x2; }
126
127#define DECLARE_COERCE_HALF_OPS(type, ret, x2, h2) \
128    DECLARE_COERCE_HALF_NUMERIC_OPS(+, type, ret, x2, h2) \
129    DECLARE_COERCE_HALF_NUMERIC_OPS(-, type, ret, x2, h2) \
130    DECLARE_COERCE_HALF_NUMERIC_OPS(*, type, ret, x2, h2) \
131    DECLARE_COERCE_HALF_NUMERIC_OPS(/, type, ret, x2, h2) \
132    \
133    DECLARE_COERCE_HALF_BOOL_OPS(==, type, x2, h2) \
134    DECLARE_COERCE_HALF_BOOL_OPS(!=, type, x2, h2) \
135    DECLARE_COERCE_HALF_BOOL_OPS(>=, type, x2, h2) \
136    DECLARE_COERCE_HALF_BOOL_OPS(<=, type, x2, h2) \
137    DECLARE_COERCE_HALF_BOOL_OPS(>, type, x2, h2) \
138    DECLARE_COERCE_HALF_BOOL_OPS(<, type, x2, h2)
139
140#define DECLARE_COERCE_TO_HALF_OPS(type) \
141    DECLARE_COERCE_HALF_OPS(type, half, (half)(int)x, h)
142
143#define DECLARE_COERCE_FROM_HALF_OPS(type) \
144    DECLARE_COERCE_HALF_OPS(type, type, x, (type)h)
145
146DECLARE_COERCE_TO_HALF_OPS(int8_t)
147DECLARE_COERCE_TO_HALF_OPS(uint8_t)
148DECLARE_COERCE_TO_HALF_OPS(int16_t)
149DECLARE_COERCE_TO_HALF_OPS(uint16_t)
150DECLARE_COERCE_TO_HALF_OPS(int32_t)
151DECLARE_COERCE_TO_HALF_OPS(uint32_t)
152DECLARE_COERCE_TO_HALF_OPS(int64_t)
153DECLARE_COERCE_TO_HALF_OPS(uint64_t)
154
155DECLARE_COERCE_FROM_HALF_OPS(float)
156DECLARE_COERCE_FROM_HALF_OPS(double)
157DECLARE_COERCE_FROM_HALF_OPS(long double)
158
159#undef DECLARE_COERCE_HALF_NUMERIC_OPS
160#undef DECLARE_COERCE_HALF_OPS
161#undef DECLARE_COERCE_TO_HALF_OPS
162#undef DECLARE_COERCE_FROM_HALF_OPS
163
164} /* namespace lol */
165
166#endif // __LOL_HALF_H__
167
Note: See TracBrowser for help on using the repository browser.