/
verifications.cpp
87 lines (74 loc) · 2.77 KB
/
verifications.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
* verifications.cpp
*
* Created on: 29 May 2016
* Author: Patrick
*/
#include <cmath>
#include "eight_rooty_pieces.h"
#include "catch/catch.hpp"
#pragma GCC diagnostic ignored "-Wparentheses"
TEST_CASE("Square roots are computed (small range)", "[algorithms]") {
for (int i = -10; i < 10; i += 1) {
double arg = pow(10, i);
CAPTURE(arg);
auto std_sqrt = sqrt(arg);
auto closed = my_sqrt(arg);
auto bablyonian = my_sqrt_bablyonian(arg);
auto newton = my_sqrt_newtonraphson(arg);
auto range = my_sqrt_range(arg);
auto naive = my_sqrt_naive(arg); // terribly inefficient
auto DOOM = my_sqrt_homage_to_carmack(arg);
auto DOOM64 = my_sqrt_homage_to_carmack64(arg);
auto inv = my_inverse_sqrt(arg);
// TODO(PMM) - check out the epsilon Approx uses
REQUIRE(std_sqrt == Approx(closed));
REQUIRE(std_sqrt == Approx(bablyonian));
REQUIRE(std_sqrt == Approx(newton));
REQUIRE(std_sqrt == Approx(range));
REQUIRE(std_sqrt == Approx(naive));
REQUIRE(std_sqrt == Approx(DOOM).epsilon(0.1));
REQUIRE(std_sqrt == Approx(DOOM64).epsilon(0.1));
REQUIRE(std_sqrt == Approx(inv));
}
}
TEST_CASE("Square roots are computed (full range)", "[algorithms]") {
// we can't call "naive" as way too slow
for (double arg = std::numeric_limits<double>::min();
arg < std::numeric_limits<double>::max(); arg *= 100) {
CAPTURE(arg);
auto std_sqrt = sqrt(arg);
auto closed = my_sqrt(arg);
auto bablyonian = my_sqrt_bablyonian(arg);
auto newton = my_sqrt_newtonraphson(arg);
auto range = my_sqrt_range(arg);
auto inv = my_inverse_sqrt(arg);
REQUIRE(std_sqrt == Approx(closed));
REQUIRE(std_sqrt == Approx(bablyonian));
REQUIRE(std_sqrt == Approx(newton));
REQUIRE(std_sqrt == Approx(range));
REQUIRE(std_sqrt == Approx(inv));
}
}
TEST_CASE("Square roots are computed (denorm range)", "[algorithms]") {
// http://stackoverflow.com/questions/20065406/whats-the-largest-denormalized-and-normalized-number64bit-iee-754-1985
for (double arg = std::numeric_limits<double>::min();
arg > std::numeric_limits<double>::denorm_min(); arg /= 10) {
CAPTURE(arg);
auto std_sqrt = sqrt(arg);
auto closed = my_sqrt(arg);
auto bablyonian = my_sqrt_bablyonian(arg);
auto newton = my_sqrt_newtonraphson(arg);
auto range = my_sqrt_range(arg);
auto DOOM = my_sqrt_homage_to_carmack(arg);
auto DOOM64 = my_sqrt_homage_to_carmack64(arg);
auto inv = my_inverse_sqrt(arg);
REQUIRE(std_sqrt == Approx(closed));
REQUIRE(std_sqrt == Approx(bablyonian));
REQUIRE(std_sqrt == Approx(newton));
REQUIRE(std_sqrt == Approx(range).epsilon(0.001));
REQUIRE(std_sqrt == Approx(DOOM));
REQUIRE(std_sqrt == Approx(DOOM64));
REQUIRE(std_sqrt == Approx(inv));
}
}