• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Google LLC
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 #include "include/private/base/SkFloatingPoint.h"
9 #include "src/base/SkUtils.h"
10 #include "tests/Test.h"
11 
12 #include <array>
13 #include <cfloat>
14 #include <cmath>
15 #include <cstddef>
16 #include <cstdint>
17 
DEF_TEST(DoubleNearlyZero,reporter)18 DEF_TEST(DoubleNearlyZero, reporter) {
19     REPORTER_ASSERT(reporter, sk_double_nearly_zero(0.));
20     REPORTER_ASSERT(reporter, sk_double_nearly_zero(-0.));
21     REPORTER_ASSERT(reporter, sk_double_nearly_zero(DBL_EPSILON));
22     REPORTER_ASSERT(reporter, sk_double_nearly_zero(-DBL_EPSILON));
23 
24     double nearly = 1. / 20000000000LL;
25     REPORTER_ASSERT(reporter, nearly != 0);
26     REPORTER_ASSERT(reporter, sk_double_nearly_zero(nearly));
27     REPORTER_ASSERT(reporter, sk_double_nearly_zero(-nearly));
28 
29     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(FLT_EPSILON));
30     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-FLT_EPSILON));
31     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(1));
32     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-1));
33     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(INFINITY));
34     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(HUGE_VALF));
35     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(HUGE_VAL));
36     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(HUGE_VALL));
37     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-INFINITY));
38     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-HUGE_VALF));
39     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-HUGE_VAL));
40     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-HUGE_VALL));
41     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(NAN));
42     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-NAN));
43 }
44 
DEF_TEST(DoubleNearlyEqualUlps,reporter)45 DEF_TEST(DoubleNearlyEqualUlps, reporter) {
46     // Our tolerance is looser than DBL_EPSILON
47     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(1., 1.));
48     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(1., 1. - DBL_EPSILON));
49     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(1., 1. + DBL_EPSILON));
50     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(100.5, 100.5));
51     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(100.5, 100.5 - DBL_EPSILON));
52     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(100.5, 100.5 + DBL_EPSILON));
53 
54 
55     // Our tolerance is tighter than FLT_EPSILON
56     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(1., 1. - FLT_EPSILON));
57     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(1., 1. + FLT_EPSILON));
58     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(100.5, 100.5 - FLT_EPSILON));
59     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(100.5, 100.5 + FLT_EPSILON));
60     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(0, 0.1));
61     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(FLT_EPSILON, 0));
62 
63     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(INFINITY, INFINITY));
64     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(INFINITY, 10));
65     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(10, INFINITY));
66 
67     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(NAN, INFINITY));
68 }
69 
DEF_TEST(BitCastDoubleRoundTrip,reporter)70 DEF_TEST(BitCastDoubleRoundTrip, reporter) {
71     std::array<double, 5>  testCases = {0.0, 1.0, -13.0, 1.234567890123456, -543210.987654321};
72 
73     for (size_t i = 0; i < testCases.size(); i++) {
74         double input = testCases[i];
75         uint64_t bits = sk_bit_cast<uint64_t>(input);
76         double output = sk_bit_cast<double>(bits);
77         REPORTER_ASSERT(reporter, input == output, "%.16f is not exactly %.16f", input, output);
78     }
79 
80     {
81         uint64_t bits = sk_bit_cast<uint64_t>((double) NAN);
82         double output = sk_bit_cast<double>(bits);
83         REPORTER_ASSERT(reporter, std::isnan(output), "%.16f is not nan", output);
84     }
85     {
86         uint64_t bits = sk_bit_cast<uint64_t>((double) INFINITY);
87         double output = sk_bit_cast<double>(bits);
88         REPORTER_ASSERT(reporter, !std::isfinite(output), "%.16f is not infinity", output);
89     }
90 }
91