OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "float.h" | 8 #include "float.h" |
9 | 9 |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 | 202 |
203 static float nextFloat(SkRandom& rand) { | 203 static float nextFloat(SkRandom& rand) { |
204 SkFloatIntUnion data; | 204 SkFloatIntUnion data; |
205 data.fSignBitInt = rand.nextU(); | 205 data.fSignBitInt = rand.nextU(); |
206 return data.fFloat; | 206 return data.fFloat; |
207 } | 207 } |
208 | 208 |
209 /* returns true if a == b as resulting from (int)x. Since it is undefined | 209 /* returns true if a == b as resulting from (int)x. Since it is undefined |
210 what to do if the float exceeds 2^32-1, we check for that explicitly. | 210 what to do if the float exceeds 2^32-1, we check for that explicitly. |
211 */ | 211 */ |
212 static bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) { | 212 static bool equal_float_native_skia(float x, int32_t ni, int32_t si) { |
213 if (!(x == x)) { // NAN | 213 // When the float is out of integer range (NaN, above, below), |
214 return ((int32_t)si) == SK_MaxS32 || ((int32_t)si) == SK_MinS32; | 214 // the C cast is undefined, but Skia's methods should have clamped. |
| 215 if (!(x == x)) { // NaN |
| 216 return si == SK_MaxS32 || si == SK_MinS32; |
215 } | 217 } |
216 // for out of range, C is undefined, but skia always should return NaN32 | |
217 if (x > SK_MaxS32) { | 218 if (x > SK_MaxS32) { |
218 return ((int32_t)si) == SK_MaxS32; | 219 return si == SK_MaxS32; |
219 } | 220 } |
220 if (x < -SK_MaxS32) { | 221 if (x < SK_MinS32) { |
221 return ((int32_t)si) == SK_MinS32; | 222 return si == SK_MinS32; |
222 } | 223 } |
223 return si == ni; | 224 return si == ni; |
224 } | 225 } |
225 | 226 |
226 static void assert_float_equal(skiatest::Reporter* reporter, const char op[], | 227 static void assert_float_equal(skiatest::Reporter* reporter, const char op[], |
227 float x, uint32_t ni, uint32_t si) { | 228 float x, int32_t ni, int32_t si) { |
228 if (!equal_float_native_skia(x, ni, si)) { | 229 if (!equal_float_native_skia(x, ni, si)) { |
229 ERRORF(reporter, "%s float %g bits %x native %x skia %x\n", | 230 ERRORF(reporter, "%s float %g bits %x native %x skia %x\n", |
230 op, x, SkFloat2Bits(x), ni, si); | 231 op, x, SkFloat2Bits(x), ni, si); |
231 } | 232 } |
232 } | 233 } |
233 | 234 |
234 static void test_float_cast(skiatest::Reporter* reporter, float x) { | |
235 int ix = (int)x; | |
236 int iix = SkFloatToIntCast(x); | |
237 assert_float_equal(reporter, "cast", x, ix, iix); | |
238 } | |
239 | |
240 static void test_float_floor(skiatest::Reporter* reporter, float x) { | 235 static void test_float_floor(skiatest::Reporter* reporter, float x) { |
241 int ix = (int)floor(x); | 236 int ix = (int)floor(x); |
242 int iix = SkFloatToIntFloor(x); | 237 int iix = SkFloatToIntFloor(x); |
243 assert_float_equal(reporter, "floor", x, ix, iix); | 238 assert_float_equal(reporter, "floor", x, ix, iix); |
244 } | 239 } |
245 | 240 |
246 static void test_float_round(skiatest::Reporter* reporter, float x) { | 241 static void test_float_round(skiatest::Reporter* reporter, float x) { |
247 double xx = x + 0.5; // need intermediate double to avoid temp loss | 242 double xx = x + 0.5; // need intermediate double to avoid temp loss |
248 int ix = (int)floor(xx); | 243 int ix = (int)floor(xx); |
249 int iix = SkFloatToIntRound(x); | 244 int iix = SkFloatToIntRound(x); |
250 assert_float_equal(reporter, "round", x, ix, iix); | 245 assert_float_equal(reporter, "round", x, ix, iix); |
251 } | 246 } |
252 | 247 |
253 static void test_float_ceil(skiatest::Reporter* reporter, float x) { | 248 static void test_float_ceil(skiatest::Reporter* reporter, float x) { |
254 int ix = (int)ceil(x); | 249 int ix = (int)ceil(x); |
255 int iix = SkFloatToIntCeil(x); | 250 int iix = SkFloatToIntCeil(x); |
256 assert_float_equal(reporter, "ceil", x, ix, iix); | 251 assert_float_equal(reporter, "ceil", x, ix, iix); |
257 } | 252 } |
258 | 253 |
259 static void test_float_conversions(skiatest::Reporter* reporter, float x) { | 254 static void test_float_conversions(skiatest::Reporter* reporter, float x) { |
260 test_float_cast(reporter, x); | |
261 test_float_floor(reporter, x); | 255 test_float_floor(reporter, x); |
262 test_float_round(reporter, x); | 256 test_float_round(reporter, x); |
263 test_float_ceil(reporter, x); | 257 test_float_ceil(reporter, x); |
264 } | 258 } |
265 | 259 |
266 static void test_int2float(skiatest::Reporter* reporter, int ival) { | |
267 float x0 = (float)ival; | |
268 float x1 = SkIntToFloatCast(ival); | |
269 REPORTER_ASSERT(reporter, x0 == x1); | |
270 } | |
271 | |
272 static void unittest_fastfloat(skiatest::Reporter* reporter) { | 260 static void unittest_fastfloat(skiatest::Reporter* reporter) { |
273 SkRandom rand; | 261 SkRandom rand; |
274 size_t i; | 262 size_t i; |
275 | 263 |
276 static const float gFloats[] = { | 264 static const float gFloats[] = { |
| 265 0.f/0.f, -0.f/0.f, 1.f/0.f, -1.f/0.f, |
277 0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3, | 266 0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3, |
278 0.000000001f, 1000000000.f, // doesn't overflow | 267 0.000000001f, 1000000000.f, // doesn't overflow |
279 0.0000000001f, 10000000000.f // does overflow | 268 0.0000000001f, 10000000000.f // does overflow |
280 }; | 269 }; |
281 for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) { | 270 for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) { |
282 test_float_conversions(reporter, gFloats[i]); | 271 test_float_conversions(reporter, gFloats[i]); |
283 test_float_conversions(reporter, -gFloats[i]); | 272 test_float_conversions(reporter, -gFloats[i]); |
284 } | 273 } |
285 | 274 |
286 for (int outer = 0; outer < 100; outer++) { | 275 for (int outer = 0; outer < 100; outer++) { |
287 rand.setSeed(outer); | 276 rand.setSeed(outer); |
288 for (i = 0; i < 100000; i++) { | 277 for (i = 0; i < 100000; i++) { |
289 float x = nextFloat(rand); | 278 float x = nextFloat(rand); |
290 test_float_conversions(reporter, x); | 279 test_float_conversions(reporter, x); |
291 } | 280 } |
292 | |
293 test_int2float(reporter, 0); | |
294 test_int2float(reporter, 1); | |
295 test_int2float(reporter, -1); | |
296 for (i = 0; i < 100000; i++) { | |
297 // for now only test ints that are 24bits or less, since we don't | |
298 // round (down) large ints the same as IEEE... | |
299 int ival = rand.nextU() & 0xFFFFFF; | |
300 test_int2float(reporter, ival); | |
301 test_int2float(reporter, -ival); | |
302 } | |
303 } | 281 } |
304 } | 282 } |
305 | 283 |
306 static float make_zero() { | 284 static float make_zero() { |
307 return sk_float_sin(0); | 285 return sk_float_sin(0); |
308 } | 286 } |
309 | 287 |
310 static void unittest_isfinite(skiatest::Reporter* reporter) { | 288 static void unittest_isfinite(skiatest::Reporter* reporter) { |
311 float nan = sk_float_asin(2); | 289 float nan = sk_float_asin(2); |
312 float inf = 1.0f / make_zero(); | 290 float inf = 1.0f / make_zero(); |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 test_divmod<int16_t>(r); | 670 test_divmod<int16_t>(r); |
693 } | 671 } |
694 | 672 |
695 DEF_TEST(divmod_s32, r) { | 673 DEF_TEST(divmod_s32, r) { |
696 test_divmod<int32_t>(r); | 674 test_divmod<int32_t>(r); |
697 } | 675 } |
698 | 676 |
699 DEF_TEST(divmod_s64, r) { | 677 DEF_TEST(divmod_s64, r) { |
700 test_divmod<int64_t>(r); | 678 test_divmod<int64_t>(r); |
701 } | 679 } |
OLD | NEW |