soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SFloat.h
1/*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef _SFloat_DEFINED_
9#define _SFloat_DEFINED_
10
11#include <stdint.h>
12#include <math.h>
13
14#define sk_float_sqrt(x) sqrtf(x)
15#define sk_float_sin(x) sinf(x)
16#define sk_float_cos(x) cosf(x)
17#define sk_float_tan(x) tanf(x)
18#define sk_float_floor(x) floorf(x)
19#define sk_float_ceil(x) ceilf(x)
20#define sk_float_abs(x) (float)::fabs(x)
21
22#define sk_float_floor2int(x) (int)sk_float_floor(x)
23#define sk_float_round2int(x) (int)sk_float_floor((x) + 0.5f)
24#define sk_float_ceil2int(x) (int)sk_float_ceil(x)
25
26//#define sk_float_rsqrt(x) sqrt(x)
27//#define SK_SUPPORT_DEPRECATED_SCALARROUND
28
29/** SK_Scalar1 is defined to be 1.0 represented as an float
30 */
31#define SK_Scalar1 (1.0f)
32/** SK_Scalar1 is defined to be 1/2 represented as an float
33 */
34#define SK_ScalarHalf (0.5f)
35/** SK_ScalarInfinity is defined to be infinity as an float
36 */
37#define SK_ScalarInfinity SK_FloatInfinity
38/** SK_ScalarNegativeInfinity is defined to be negative infinity as an float
39 */
40#define SK_ScalarNegativeInfinity SK_FloatNegativeInfinity
41/** SK_ScalarMax is defined to be the largest value representable as an float
42 */
43#define SK_ScalarMax (3.402823466e+38f)
44/** SK_ScalarMin is defined to be the smallest value representable as an float
45 */
46#define SK_ScalarMin (-SK_ScalarMax)
47/** SK_ScalarNaN is defined to be 'Not a Number' as an float
48 */
49#define SK_ScalarNaN SK_FloatNaN
50
51/** SkIntToScalar(n) returns its integer argument as an float
52 */
53#define SkIntToScalar(n) ((float)(n))
54/** SkFixedToScalar(n) returns its SkFixed argument as an float
55 */
56#define SkFixedToScalar(x) SkFixedToFloat(x)
57/** SFloatToFixed(n) returns its float argument as an SkFixed
58 */
59#define SFloatToFixed(x) SkFloatToFixed(x)
60
61#define SFloatToFloat(n) (n)
62#ifndef SK_SCALAR_TO_FLOAT_EXCLUDED
63#define SkFloatToScalar(n) (n)
64#endif
65
66#define SFloatToDouble(n) (double)(n)
67#define SkDoubleToScalar(n) (float)(n)
68
69/** SFloatFraction(x) returns the signed fractional part of the argument
70 */
71#define SFloatFraction(x) sk_float_mod(x, 1.0f)
72
73#define SFloatFloorToScalar(x) sk_float_floor(x)
74#define SFloatCeilToScalar(x) sk_float_ceil(x)
75#define SFloatRoundToScalar(x) sk_float_floor((x) + 0.5f)
76
77#define SFloatFloorToInt(x) sk_float_floor2int(x)
78#define SFloatCeilToInt(x) sk_float_ceil2int(x)
79#define SFloatRoundToInt(x) sk_float_round2int(x)
80#define SFloatTruncToInt(x) static_cast<int>(x)
81
82#define SK_ANNOTATE_UNPROTECTED_READ(x) (x)
83#define SK_ANNOTATE_UNPROTECTED_WRITE(ptr, val) *(ptr) = (val)
84
85/** Returns the absolute value of the specified float
86 */
87#define SFloatAbs(x) sk_float_abs(x)
88/** Return x with the sign of y
89 */
90#define SFloatCopySign(x, y) sk_float_copysign(x, y)
91/** Returns the product of two SFloats
92 */
93#define SFloatMul(a, b) ((float)(a) * (b))
94/** Returns the product of two SFloats plus a third float
95 */
96#define SFloatMulAdd(a, b, c) ((float)(a) * (b) + (c))
97/** Returns the quotient of two SFloats (a/b)
98 */
99#define SFloatDiv(a, b) ((float)(a) / (b))
100/** Returns the mod of two SFloats (a mod b)
101 */
102#define SFloatMod(x, y) sk_float_mod(x, y)
103/** Returns the product of the first two arguments, divided by the third argument
104 */
105#define SFloatMulDiv(a, b, c) ((float)(a) * (b) / (c))
106/** Returns the multiplicative inverse of the float (1/x)
107 */
108#define SFloatInvert(x) (SK_Scalar1 / (x))
109#define SFloatFastInvert(x) (SK_Scalar1 / (x))
110/** Returns the square root of the float
111 */
112#define SFloatSqrt(x) sk_float_sqrt(x)
113/** Returns b to the e
114 */
115#define SFloatPow(b, e) sk_float_pow(b, e)
116/** Returns the average of two SFloats (a+b)/2
117 */
118#define SFloatAve(a, b) (((a) + (b)) * 0.5f)
119/** Returns one half of the specified float
120 */
121#define SFloatHalf(a) ((a)*0.5f)
122
123#define SK_ScalarSqrt2 1.41421356f
124#define SK_ScalarPI 3.14159265f
125#define SK_ScalarTanPIOver8 0.414213562f
126#define SK_ScalarRoot2Over2 0.707106781f
127
128#define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180))
129#define SkRadiansToDegrees(radians) ((radians) * (180 / SK_ScalarPI))
130#define SFloatSin(radians) (float)sk_float_sin(radians)
131#define SFloatCos(radians) (float)sk_float_cos(radians)
132#define SFloatTan(radians) (float)sk_float_tan(radians)
133#define SFloatASin(val) (float)sk_float_asin(val)
134#define SFloatACos(val) (float)sk_float_acos(val)
135#define SFloatATan2(y, x) (float)sk_float_atan2(y, x)
136#define SFloatExp(x) (float)sk_float_exp(x)
137#define SFloatLog(x) (float)sk_float_log(x)
138
139SNSBEGIN
140/**
141 * Variant of SFloatRoundToInt, that performs the rounding step (adding 0.5) explicitly using
142 * double, to avoid possibly losing the low bit(s) of the answer before calling floor().
143 *
144 * This routine will likely be slower than SFloatRoundToInt(), and should only be used when the
145 * extra precision is known to be valuable.
146 *
147 * In particular, this catches the following case:
148 * float x = 0.49999997;
149 * int ix = SFloatRoundToInt(x);
150 * SASSERT(0 == ix); // <--- fails
151 * ix = SkDScalarRoundToInt(x);
152 * SASSERT(0 == ix); // <--- succeeds
153 */
154inline int SkDScalarRoundToInt(float x)
155{
156 double xx = x;
157 xx += 0.5;
158 return (int)floor(xx);
159}
160inline float SkMaxScalar(float a, float b)
161{
162 return a > b ? a : b;
163}
164inline float SkMinScalar(float a, float b)
165{
166 return a < b ? a : b;
167}
168
169/** SFloatIsNaN(n) returns true if argument is not a number
170 */
171inline bool SFloatIsNaN(float x)
172{
173 return x != x;
174}
175
176/** Returns true if x is not NaN and not infinite */
177inline bool SFloatIsFinite(float x)
178{
179 // We rely on the following behavior of infinities and nans
180 // 0 * finite --> 0
181 // 0 * infinity --> NaN
182 // 0 * NaN --> NaN
183 float prod = x * 0;
184 // At this point, prod will either be NaN or 0
185 // Therefore we can return (prod == prod) or (0 == prod).
186 return prod == prod;
187}
188
189/** Returns the value pinned between 0 and max inclusive
190 */
191inline float SFloatClampMax(float x, float max)
192{
193 return x < 0 ? 0 : x > max ? max : x;
194}
195/** Returns the value pinned between min and max inclusive
196 */
197inline float SFloatPin(float x, float min, float max)
198{
199 return x < min ? min : x > max ? max : x;
200}
201/** Returns the specified float squared (x*x)
202 */
203inline float SFloatSquare(float x)
204{
205 return x * x;
206}
207
208inline bool SFloatIsInt(float x)
209{
210 return x == (float)(int)x;
211}
212
213/**
214 * Returns -1 || 0 || 1 depending on the sign of value:
215 * -1 if x < 0
216 * 0 if x == 0
217 * 1 if x > 0
218 */
219inline int SFloatSignAsInt(float x)
220{
221 return x < 0 ? -1 : (x > 0);
222}
223
224// Scalar result version of above
225inline float SFloatSignAsScalar(float x)
226{
227 return x < 0 ? -SK_Scalar1 : ((x > 0) ? SK_Scalar1 : 0);
228}
229
230#define SK_ScalarNearlyZero (SK_Scalar1 / (1 << 12))
231
232inline bool SFloatNearlyZero(float x, float tolerance = SK_ScalarNearlyZero)
233{
234 SASSERT(tolerance >= 0);
235 return SFloatAbs(x) <= tolerance;
236}
237
238inline bool SFloatNearlyEqual(float x, float y, float tolerance = SK_ScalarNearlyZero)
239{
240 SASSERT(tolerance >= 0);
241 return SFloatAbs(x - y) <= tolerance;
242}
243
244/** Linearly interpolate between A and B, based on t.
245 If t is 0, return A
246 If t is 1, return B
247 else interpolate.
248 t must be [0..SK_Scalar1]
249*/
250inline float SFloatInterp(float A, float B, float t)
251{
252 SASSERT(t >= 0 && t <= SK_Scalar1);
253 return A + (B - A) * t;
254}
255
256/*
257 * Helper to compare an array of scalars.
258 */
259inline bool SFloatsEqual(const float a[], const float b[], int n)
260{
261 SASSERT(n >= 0);
262 for (int i = 0; i < n; ++i)
263 {
264 if (a[i] != b[i])
265 {
266 return false;
267 }
268 }
269 return true;
270}
271
272SNSEND
273#endif