26 double A,
double B,
double C,
31 "Invalid test case, up to 2 roots allowed");
33 for (
size_t i = 0;
i < expectedRoots.
size();
i++) {
34 double x = expectedRoots[
i];
36 double y =
A *
x *
x +
B *
x +
C;
38 "Invalid test case root %zu. %.16f != 0",
i,
y);
42 "Invalid test case root %zu. Roots should be sorted in ascending order",
i);
48 double roots[2] = {0, 0};
51 "Wrong number of roots returned %zu != %d", expectedRoots.
size(),
57 for (
int i = 0;
i < rootCount;
i++) {
60 "0 != %.16f at index %d",
roots[
i],
i);
64 "%.16f != %.16f at index %d", expectedRoots[
i],
roots[
i],
i);
70 double roots[2] = {0, 0};
73 "Wrong number of roots returned %zu != %d", expectedRoots.
size(),
79 for (
int i = 0;
i < rootCount;
i++) {
82 "0 != %.16f at index %d",
roots[
i],
i);
86 "%.16f != %.16f at index %d", expectedRoots[
i],
roots[
i],
i);
137 0.2929016490705016, 0.0000030451558069, 0,
138 {-0.00001039651301576329, 0});
149 4.3719914983870202e+291, 1.0269509510194551e+152, 0,
155 0x1p-1055, 0x1.3000006p-1044, -0x1.c000008p+1009,
185 "Discriminant is negative infinity"
211 int64_t
F[] = {1, 1, 0};
213 for (
int i = 2;
i < 79; ++
i) {
216 const int expectedDiscriminant =
i % 2 == 0 ? 1 : -1;
245 int64_t
F[] = {1, 1, 0};
247 for (
int i = 2;
i < 79; ++
i) {
250 const int expectedDiscriminant =
i % 2 == 0 ? 1 : -1;
256 const double expectedLittle = ((double)
F[1] - 1) /
F[0];
257 const double expectedBig = ((double)
F[1] + 1) /
F[0];
288 const double nan = std::numeric_limits<double>::quiet_NaN();
289 const double infinity = std::numeric_limits<double>::infinity();
291 auto specialEqual = [] (
double actual,
double test) {
292 if (std::isnan(actual)) {
293 return std::isnan(
test);
296 if (std::isinf(actual)) {
297 return std::isinf(
test);
301 const double errorFactor =
std::sqrt(std::numeric_limits<double>::epsilon());
305 auto p2 = [](
double a) {
313 {2.0 * p2(600), 0, 2.0 * p2(600), nan, nan},
314 {-2.0 * p2(600), 0, -2.0 * p2(600), nan, nan},
317 {0, 0, 0, infinity, infinity},
320 {0, 3, 4, -4.0/3.0, -4.0/3.0},
321 {0, p2(600), -p2(600), 1, 1},
322 {0, p2(600), p2(600), -1, -1},
323 {0, p2(-600), p2(600), -infinity, -infinity},
324 {0, p2(600), p2(-600), 0, 0},
325 {0, 2, -1.0e-323, 5.0e-324, 5.0e-324},
327 {p2(600), 0, 0, 0, 0},
328 {2, 0, -3, -
sqrt(3.0/2.0),
sqrt(3.0/2.0)},
330 {3, 2, 0, -2.0/3.0, 0},
332 {p2(-600), p2(700), 0, -infinity, 0},
333 {p2(600), p2(-700), 0, 0, 0},
336 {1, -1, -1, -0.6180339887498948, 1.618033988749895},
337 {1, 1 + p2(-52), 0.25 + p2(-53), (-1 - p2(-51)) / 2.0, -0.5},
338 {1, p2(-511) + p2(-563), std::exp2(-1024), -7.458340888372987e-155,-7.458340574027429e-155},
339 {1, p2(27), 0.75, -134217728.0, -5.587935447692871e-09},
340 {1, -1e9, 1, 1
e-09, 1000000000.0},
342 {p2(600), 0.5, -p2(-600), -3.086568504549085e-181, 1.8816085719976428e-181},
345 {1, p2(26), -0.125, -67108864.0, 1.862645149230957e-09},
347 {p2(600), -p2(-600), -p2(-600), -2.409919865102884e-181, 2.409919865102884e-181},
350 {-158114166017, 316227766017, -158113600000, 0.99999642020057874, 1},
351 {-312499999999.0, 707106781186.0, -400000000000.0, 1.131369396027, 1.131372303775},
352 {-67, 134, -65, 0.82722631488372798, 1.17277368511627202},
353 {0.247260273973, 0.994520547945, -0.138627953316, -4.157030027041105, 0.1348693622211607},
354 {1, -2300000, 2.0e11, 90518.994979145, 2209481.005020854},
355 {1.5*p2(-1026), 0, -p2(1022), -1.4678102981723264e308, 1.4678102981723264e308},
358 {1.5*p2(-1026), 0, -p2(1022), -1.4678102981723264e308, 1.4678102981723264e308},
361 for (
auto testCase : cases) {
362 double A = testCase.
A,
365 answerLo = testCase.answerLo,
366 answerHi = testCase.answerHi;
static void testQuadRootsReal(skiatest::Reporter *reporter, const std::string &name, double A, double B, double C, SkSpan< const double > expectedRoots)
DEF_TEST(QuadRootsReal_ActualQuadratics, reporter)
bool sk_double_nearly_zero(double a)
static bool SkIsFinite(T x, Pack... values)
bool sk_doubles_nearly_equal_ulps(double a, double b, uint8_t maxUlpsDiff=16)
static std::vector< SkPDFIndirectReference > sort(const THashSet< SkPDFIndirectReference > &src)
#define REPORTER_ASSERT(r, cond,...)
static double Discriminant(double A, double B, double C)
static RootResult Roots(double A, double B, double C)
static int RootsReal(double A, double B, double C, double solution[2])
constexpr size_t size() const
static const char * begin(const StringSlice &s)
static float max(float r, float g, float b)
static float min(float r, float g, float b)
DEF_SWITCHES_START aot vmservice shared library name
SIN Vec< N, float > abs(const Vec< N, float > &x)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
static int RootsReal(double A, double B, double C, double t[2])