summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2014-11-03 17:03:20 -0800
committerElliott Hughes <enh@google.com>2014-11-04 18:00:02 -0800
commit1b37ba2178d618221905e17436f38e0c5a8397f3 (patch)
treebdd2e0a562113f74cedabc1e8428a43a201bfaae
parent695781b6f0419f82939176a6ec1a240300d9f036 (diff)
downloadbionic-1b37ba2178d618221905e17436f38e0c5a8397f3.zip
bionic-1b37ba2178d618221905e17436f38e0c5a8397f3.tar.gz
bionic-1b37ba2178d618221905e17436f38e0c5a8397f3.tar.bz2
Improve math tests to allow a specific ulp bound.
At the moment our libm is only good enough for a 1 ulp bound on these tests, but that's better than the 4 ulp bound you get from gtest by default. I'm not really happy with the multiple structures and corresponding functions, but at least they mean there's no duplication in the tests themselves, and it should be easy enough for us to make further improvements in future. Change-Id: I004e12970332e1d9531721361d6c34f908cfcecc
-rw-r--r--tests/Android.mk14
-rw-r--r--tests/math_cos_intel_data.h (renamed from tests/math_cos_test.cpp)26
-rw-r--r--tests/math_cosf_intel_data.h (renamed from tests/math_cosf_test.cpp)26
-rw-r--r--tests/math_data_test.h148
-rw-r--r--tests/math_exp_intel_data.h (renamed from tests/math_exp_test.cpp)26
-rw-r--r--tests/math_expf_intel_data.h (renamed from tests/math_expf_test.cpp)26
-rw-r--r--tests/math_log_intel_data.h (renamed from tests/math_log_test.cpp)26
-rw-r--r--tests/math_logf_intel_data.h (renamed from tests/math_logf_test.cpp)26
-rw-r--r--tests/math_pow_intel_data.h (renamed from tests/math_pow_test.cpp)27
-rw-r--r--tests/math_powf_intel_data.h (renamed from tests/math_powf_test.cpp)27
-rw-r--r--tests/math_sin_intel_data.h (renamed from tests/math_sin_test.cpp)26
-rw-r--r--tests/math_sincos_intel_data.h (renamed from tests/math_sincos_test.cpp)32
-rw-r--r--tests/math_sincosf_intel_data.h (renamed from tests/math_sincosf_test.cpp)30
-rw-r--r--tests/math_sinf_intel_data.h (renamed from tests/math_sinf_test.cpp)26
-rw-r--r--tests/math_tan_intel_data.h (renamed from tests/math_tan_test.cpp)26
-rw-r--r--tests/math_tanf_intel_data.h (renamed from tests/math_tanf_test.cpp)26
-rw-r--r--tests/math_test.cpp122
17 files changed, 254 insertions, 406 deletions
diff --git a/tests/Android.mk b/tests/Android.mk
index 66b1655..1a7a5e0 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -67,20 +67,6 @@ libBionicStandardTests_src_files := \
libgen_test.cpp \
locale_test.cpp \
malloc_test.cpp \
- math_cos_test.cpp \
- math_cosf_test.cpp \
- math_exp_test.cpp \
- math_expf_test.cpp \
- math_log_test.cpp \
- math_logf_test.cpp \
- math_pow_test.cpp \
- math_powf_test.cpp \
- math_sin_test.cpp \
- math_sinf_test.cpp \
- math_sincos_test.cpp \
- math_sincosf_test.cpp \
- math_tan_test.cpp \
- math_tanf_test.cpp \
math_test.cpp \
mntent_test.cpp \
netdb_test.cpp \
diff --git a/tests/math_cos_test.cpp b/tests/math_cos_intel_data.h
index 4917e87..22ec0bc 100644
--- a/tests/math_cos_test.cpp
+++ b/tests/math_cos_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- double expected;
- double call_data;
-} cos_intel_data_t;
-
-static cos_intel_data_t g_cos_intel_data[] = {
+static data_1_1_t<double, double> g_cos_intel_data[] = {
{ // Entry 0
0x1.c1a27ae836f128000000000000504e9bp-1,
0x1.feb1f7920e248p-2
@@ -5632,15 +5620,3 @@ static cos_intel_data_t g_cos_intel_data[] = {
-0.0
},
};
-#endif // __BIONIC__
-
-TEST(math_cos, cos_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_cos_intel_data)/sizeof(cos_intel_data_t); i++) {
- EXPECT_DOUBLE_EQ(g_cos_intel_data[i].expected, cos(g_cos_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_cosf_test.cpp b/tests/math_cosf_intel_data.h
index 8520c1d..d606021 100644
--- a/tests/math_cosf_test.cpp
+++ b/tests/math_cosf_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- float expected;
- float call_data;
-} cosf_intel_data_t;
-
-static cosf_intel_data_t g_cosf_intel_data[] = {
+static data_1_1_t<float, float> g_cosf_intel_data[] = {
{ // Entry 0
0x1.bc7b66ffb7689d646dd1af83e9661d2dp-1,
-0x1.09ebacp-1
@@ -4344,15 +4332,3 @@ static cosf_intel_data_t g_cosf_intel_data[] = {
-0.0f
},
};
-#endif // __BIONIC__
-
-TEST(math_cosf, cosf_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_cosf_intel_data)/sizeof(cosf_intel_data_t); i++) {
- EXPECT_FLOAT_EQ(g_cosf_intel_data[i].expected, cosf(g_cosf_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_data_test.h b/tests/math_data_test.h
new file mode 100644
index 0000000..f3d25ef
--- /dev/null
+++ b/tests/math_data_test.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <fenv.h>
+
+template <typename RT, typename T1>
+struct data_1_1_t {
+ RT expected;
+ T1 input;
+};
+
+template <typename RT, typename T1, typename T2>
+struct data_1_2_t {
+ RT expected;
+ T1 input1;
+ T2 input2;
+};
+
+template <typename RT1, typename RT2, typename T>
+struct data_2_1_t {
+ RT1 expected1;
+ RT2 expected2;
+ T input;
+};
+
+template <typename T> union fp_u;
+
+template <> union fp_u<float> {
+ float value;
+ struct {
+ unsigned frac:23;
+ unsigned exp:8;
+ unsigned sign:1;
+ } bits;
+ uint32_t sign_magnitude;
+};
+
+template <> union fp_u<double> {
+ double value;
+ struct {
+ unsigned fracl;
+ unsigned frach:20;
+ unsigned exp:11;
+ unsigned sign:1;
+ } bits;
+ uint64_t sign_magnitude;
+};
+
+// TODO: long double.
+
+template <typename T>
+static inline auto SignAndMagnitudeToBiased(const T& value) -> decltype(fp_u<T>::sign_magnitude) {
+ fp_u<T> u;
+ u.value = value;
+ if (u.bits.sign) {
+ return ~u.sign_magnitude + 1;
+ } else {
+ u.bits.sign = 1;
+ return u.sign_magnitude;
+ }
+}
+
+// Based on the existing googletest implementation, which uses a fixed 4 ulp bound.
+template <typename T>
+size_t UlpDistance(T lhs, T rhs) {
+ const auto biased1 = SignAndMagnitudeToBiased(lhs);
+ const auto biased2 = SignAndMagnitudeToBiased(rhs);
+ return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
+}
+
+template <size_t ULP, typename T>
+struct FpUlpEq {
+ ::testing::AssertionResult operator()(const char* /* expected_expression */,
+ const char* /* actual_expression */,
+ T expected,
+ T actual) {
+ if (!isnan(expected) && !isnan(actual) && UlpDistance(expected, actual) <= ULP) {
+ return ::testing::AssertionSuccess();
+ }
+
+ // Output the actual and expected values as hex floating point.
+ char expected_str[64];
+ char actual_str[64];
+ snprintf(expected_str, sizeof(expected_str), "%a", expected);
+ snprintf(actual_str, sizeof(actual_str), "%a", actual);
+
+ return ::testing::AssertionFailure()
+ << "expected (" << expected_str << ") != actual (" << actual_str << ")";
+ }
+};
+
+// Runs through the array 'data' applying 'f' to each of the input values
+// and asserting that the result is within ULP ulps of the expected value.
+// For testing a (double) -> double function like sin(3).
+template <size_t ULP, typename RT, typename T, size_t N>
+void DoMathDataTest(data_1_1_t<RT, T> (&data)[N], RT f(T)) {
+ fesetenv(FE_DFL_ENV);
+ FpUlpEq<ULP, RT> predicate;
+ for (size_t i = 0; i < N; ++i) {
+ EXPECT_PRED_FORMAT2(predicate,
+ data[i].expected, f(data[i].input)) << "Failed on element " << i;
+ }
+}
+
+// Runs through the array 'data' applying 'f' to each of the pairs of input values
+// and asserting that the result is within ULP ulps of the expected value.
+// For testing a (double, double) -> double function like pow(3).
+template <size_t ULP, typename RT, typename T1, typename T2, size_t N>
+void DoMathDataTest(data_1_2_t<RT, T1, T2> (&data)[N], RT f(T1, T2)) {
+ fesetenv(FE_DFL_ENV);
+ FpUlpEq<ULP, RT> predicate;
+ for (size_t i = 0; i < N; ++i) {
+ EXPECT_PRED_FORMAT2(predicate,
+ data[i].expected, f(data[i].input1, data[i].input2)) << "Failed on element " << i;
+ }
+}
+
+// Runs through the array 'data' applying 'f' to each of the input values
+// and asserting that the results are within ULP ulps of the expected values.
+// For testing a (double, double*, double*) -> void function like sincos(3).
+template <size_t ULP, typename RT1, typename RT2, typename T1, size_t N>
+void DoMathDataTest(data_2_1_t<RT1, RT2, T1> (&data)[N], void f(T1, RT1*, RT2*)) {
+ fesetenv(FE_DFL_ENV);
+ FpUlpEq<ULP, RT1> predicate1;
+ FpUlpEq<ULP, RT2> predicate2;
+ for (size_t i = 0; i < N; ++i) {
+ RT1 out1;
+ RT2 out2;
+ f(data[i].input, &out1, &out2);
+ EXPECT_PRED_FORMAT2(predicate1, data[i].expected1, out1) << "Failed on element " << i;
+ EXPECT_PRED_FORMAT2(predicate2, data[i].expected2, out2) << "Failed on element " << i;
+ }
+}
diff --git a/tests/math_exp_test.cpp b/tests/math_exp_intel_data.h
index c9c6ad5..0ca3813 100644
--- a/tests/math_exp_test.cpp
+++ b/tests/math_exp_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- double expected;
- double call_data;
-} exp_intel_data_t;
-
-static exp_intel_data_t g_exp_intel_data[] = {
+static data_1_1_t<double, double> g_exp_intel_data[] = {
{ // Entry 0
0x1.0000000000001fffffffffffffffffffp0,
0x1.ffffffffffffep-52
@@ -1964,15 +1952,3 @@ static exp_intel_data_t g_exp_intel_data[] = {
-0x1.6232bdd7abcd3p9
},
};
-#endif // __BIONIC__
-
-TEST(math_exp, exp_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_exp_intel_data)/sizeof(exp_intel_data_t); i++) {
- EXPECT_DOUBLE_EQ(g_exp_intel_data[i].expected, exp(g_exp_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_expf_test.cpp b/tests/math_expf_intel_data.h
index 30bc946..7007458 100644
--- a/tests/math_expf_test.cpp
+++ b/tests/math_expf_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- float expected;
- float call_data;
-} expf_intel_data_t;
-
-static expf_intel_data_t g_expf_intel_data[] = {
+static data_1_1_t<float, float> g_expf_intel_data[] = {
{ // Entry 0
0x1.e0fabf081222780d74c00fda30aa3943p-1,
-0x1.000006p-4
@@ -1428,15 +1416,3 @@ static expf_intel_data_t g_expf_intel_data[] = {
-0x1.5d58a0p6
},
};
-#endif // __BIONIC__
-
-TEST(math_expf, expf_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_expf_intel_data)/sizeof(expf_intel_data_t); i++) {
- EXPECT_FLOAT_EQ(g_expf_intel_data[i].expected, expf(g_expf_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_log_test.cpp b/tests/math_log_intel_data.h
index 4f136a7..95ae60e 100644
--- a/tests/math_log_test.cpp
+++ b/tests/math_log_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- double expected;
- double call_data;
-} log_intel_data_t;
-
-static log_intel_data_t g_log_intel_data[] = {
+static data_1_1_t<double, double> g_log_intel_data[] = {
{ // Entry 0
0x1.d77fd13d27ffefffffffffffb5ed9843p-11,
0x1.003af6c37c1d3p0
@@ -1664,15 +1652,3 @@ static log_intel_data_t g_log_intel_data[] = {
-0.0
},
};
-#endif // __BIONIC__
-
-TEST(math_log, log_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_log_intel_data)/sizeof(log_intel_data_t); i++) {
- EXPECT_DOUBLE_EQ(g_log_intel_data[i].expected, log(g_log_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_logf_test.cpp b/tests/math_logf_intel_data.h
index ca02095..b69776c 100644
--- a/tests/math_logf_test.cpp
+++ b/tests/math_logf_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- float expected;
- float call_data;
-} logf_intel_data_t;
-
-static logf_intel_data_t g_logf_intel_data[] = {
+static data_1_1_t<float, float> g_logf_intel_data[] = {
{ // Entry 0
-0x1.bb9d3aeb8c87b02d7763eba8b48a102dp1,
0x1.000002p-5
@@ -1316,15 +1304,3 @@ static logf_intel_data_t g_logf_intel_data[] = {
-0.0f
},
};
-#endif // __BIONIC__
-
-TEST(math_logf, logf_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_logf_intel_data)/sizeof(logf_intel_data_t); i++) {
- EXPECT_FLOAT_EQ(g_logf_intel_data[i].expected, logf(g_logf_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_pow_test.cpp b/tests/math_pow_intel_data.h
index a4caa36..ac9f5af 100644
--- a/tests/math_pow_test.cpp
+++ b/tests/math_pow_intel_data.h
@@ -14,20 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- double expected;
- double x_call_data;
- double y_call_data;
-} pow_intel_data_t;
-
-static pow_intel_data_t g_pow_intel_data[] = {
+static data_1_2_t<double, double, double> g_pow_intel_data[] = {
{ // Entry 0
0x1.p0,
-0x1.0p-10, 0.0
@@ -3289,15 +3276,3 @@ static pow_intel_data_t g_pow_intel_data[] = {
0x1.4p3, 0x1.4p3
},
};
-#endif // __BIONIC__
-
-TEST(math_pow, pow_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_pow_intel_data)/sizeof(pow_intel_data_t); i++) {
- EXPECT_DOUBLE_EQ(g_pow_intel_data[i].expected, pow(g_pow_intel_data[i].x_call_data, g_pow_intel_data[i].y_call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_powf_test.cpp b/tests/math_powf_intel_data.h
index 7272644..3a1765b 100644
--- a/tests/math_powf_test.cpp
+++ b/tests/math_powf_intel_data.h
@@ -14,20 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- float expected;
- float x_call_data;
- float y_call_data;
-} powf_intel_data_t;
-
-static powf_intel_data_t g_powf_intel_data[] = {
+static data_1_2_t<float, float, float> g_powf_intel_data[] = {
{ // Entry 0
HUGE_VALF,
-0.0, -0x1.000002p-1
@@ -2777,15 +2764,3 @@ static powf_intel_data_t g_powf_intel_data[] = {
0x1.40p3, 0x1.40p3
},
};
-#endif // __BIONIC__
-
-TEST(math_powf, powf_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_powf_intel_data)/sizeof(powf_intel_data_t); i++) {
- EXPECT_FLOAT_EQ(g_powf_intel_data[i].expected, powf(g_powf_intel_data[i].x_call_data, g_powf_intel_data[i].y_call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_sin_test.cpp b/tests/math_sin_intel_data.h
index 509642c..c341cfe 100644
--- a/tests/math_sin_test.cpp
+++ b/tests/math_sin_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- double expected;
- double call_data;
-} sin_intel_data_t;
-
-static sin_intel_data_t g_sin_intel_data[] = {
+static data_1_1_t<double, double> g_sin_intel_data[] = {
{ // Entry 0
0x1.9259e3708bd39ffffffffffffff1bdbep-5,
0x1.9283586503fe0p-5
@@ -5784,15 +5772,3 @@ static sin_intel_data_t g_sin_intel_data[] = {
-0.0
},
};
-#endif // __BIONIC__
-
-TEST(math_sin, sin_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_sin_intel_data)/sizeof(sin_intel_data_t); i++) {
- EXPECT_DOUBLE_EQ(g_sin_intel_data[i].expected, sin(g_sin_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_sincos_test.cpp b/tests/math_sincos_intel_data.h
index 4093fb9..71ba6b1 100644
--- a/tests/math_sincos_test.cpp
+++ b/tests/math_sincos_intel_data.h
@@ -14,22 +14,7 @@
* limitations under the License.
*/
-#define _GNU_SOURCE 1
-
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- double sin_expected;
- double cos_expected;
- double call_data;
-} sincos_intel_data_t;
-
-static sincos_intel_data_t g_sincos_intel_data[] = {
+static data_2_1_t<double, double, double> g_sincos_intel_data[] = {
{ // Entry 0
-0x1.ce9a94ea9c2ad95597b1193b2300d19ap-1,
-0x1.b6d3057776dc38335b16745f2d756ab6p-2,
@@ -4776,18 +4761,3 @@ static sincos_intel_data_t g_sincos_intel_data[] = {
-0.0,
},
};
-#endif // __BIONIC__
-
-TEST(math_sincos, sincos_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_sincos_intel_data)/sizeof(sincos_intel_data_t); i++) {
- double dsin, dcos;
- sincos(g_sincos_intel_data[i].call_data, &dsin, &dcos);
- EXPECT_DOUBLE_EQ(g_sincos_intel_data[i].sin_expected, dsin) << "Failed on element " << i;
- EXPECT_DOUBLE_EQ(g_sincos_intel_data[i].cos_expected, dcos) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_sincosf_test.cpp b/tests/math_sincosf_intel_data.h
index d30f72e..5b1b535 100644
--- a/tests/math_sincosf_test.cpp
+++ b/tests/math_sincosf_intel_data.h
@@ -14,20 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- float sin_expected;
- float cos_expected;
- float call_data;
-} sincosf_intel_data_t;
-
-static sincosf_intel_data_t g_sincosf_intel_data[] = {
+static data_2_1_t<float, float, float> g_sincosf_intel_data[] = {
{ // Entry 0
-0x1.b6a7abffaf59a5ac181e3e1abf961698p-1,
0x1.080e74c116863cfab82a0fd59c71b363p-1,
@@ -4644,18 +4631,3 @@ static sincosf_intel_data_t g_sincosf_intel_data[] = {
-0.0f,
},
};
-#endif // __BIONIC__
-
-TEST(math_sincosf, sincosf_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_sincosf_intel_data)/sizeof(sincosf_intel_data_t); i++) {
- float fsin, fcos;
- sincosf(g_sincosf_intel_data[i].call_data, &fsin, &fcos);
- EXPECT_FLOAT_EQ(g_sincosf_intel_data[i].sin_expected, fsin) << "Failed on element " << i;
- EXPECT_FLOAT_EQ(g_sincosf_intel_data[i].cos_expected, fcos) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_sinf_test.cpp b/tests/math_sinf_intel_data.h
index 0c2e6f1..9cda0fd 100644
--- a/tests/math_sinf_test.cpp
+++ b/tests/math_sinf_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- float expected;
- float call_data;
-} sinf_intel_data_t;
-
-static sinf_intel_data_t g_sinf_intel_data[] = {
+static data_1_1_t<float, float> g_sinf_intel_data[] = {
{ // Entry 0
-0x1.0003fffffff554d5535552cccf778ccdp-21,
-0x1.0004p-21
@@ -4384,15 +4372,3 @@ static sinf_intel_data_t g_sinf_intel_data[] = {
-0.0f
},
};
-#endif // __BIONIC__
-
-TEST(math_sinf, sinf_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_sinf_intel_data)/sizeof(sinf_intel_data_t); i++) {
- EXPECT_FLOAT_EQ(g_sinf_intel_data[i].expected, sinf(g_sinf_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_tan_test.cpp b/tests/math_tan_intel_data.h
index e555ef3..32d733e 100644
--- a/tests/math_tan_test.cpp
+++ b/tests/math_tan_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- double expected;
- double call_data;
-} tan_intel_data_t;
-
-static tan_intel_data_t g_tan_intel_data[] = {
+static data_1_1_t<double, double> g_tan_intel_data[] = {
{ // Entry 0
0x1.5078cebff9c728000000000000024df8p-5,
0x1.50486b2f87014p-5
@@ -5192,15 +5180,3 @@ static tan_intel_data_t g_tan_intel_data[] = {
-0.0
},
};
-#endif // __BIONIC__
-
-TEST(math_tan, tan_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_tan_intel_data)/sizeof(tan_intel_data_t); i++) {
- EXPECT_DOUBLE_EQ(g_tan_intel_data[i].expected, tan(g_tan_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_tanf_test.cpp b/tests/math_tanf_intel_data.h
index db04116..0669115 100644
--- a/tests/math_tanf_test.cpp
+++ b/tests/math_tanf_intel_data.h
@@ -14,19 +14,7 @@
* limitations under the License.
*/
-#include <math.h>
-
-#include <fenv.h>
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-typedef struct {
- float expected;
- float call_data;
-} tanf_intel_data_t;
-
-static tanf_intel_data_t g_tanf_intel_data[] = {
+static data_1_1_t<float, float> g_tanf_intel_data[] = {
{ // Entry 0
-0x1.00000000001555555555577777777777p-21,
-0x1.p-21
@@ -4448,15 +4436,3 @@ static tanf_intel_data_t g_tanf_intel_data[] = {
-0.0f
},
};
-#endif // __BIONIC__
-
-TEST(math_tanf, tanf_intel) {
-#if defined(__BIONIC__)
- fesetenv(FE_DFL_ENV);
- for (size_t i = 0; i < sizeof(g_tanf_intel_data)/sizeof(tanf_intel_data_t); i++) {
- EXPECT_FLOAT_EQ(g_tanf_intel_data[i].expected, tanf(g_tanf_intel_data[i].call_data)) << "Failed on element " << i;
- }
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.";
-#endif // __BIONIC__
-}
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 538ebb1..e14d3dd 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#define _GNU_SOURCE 1
+#include <math.h>
+
// This include (and the associated definition of __test_capture_signbit)
// must be placed before any files that include <cmath> (gtest.h in this case).
//
@@ -29,7 +32,6 @@
// sure that we're testing the bionic version of signbit. The C++ libraries
// are free to reimplement signbit or delegate to compiler builtins if they
// please.
-#include <math.h>
namespace {
template<typename T> inline int test_capture_signbit(const T in) {
@@ -46,6 +48,8 @@ template<typename T> inline int test_capture_isinf(const T in) {
}
}
+#include "math_data_test.h"
+
#include <gtest/gtest.h>
#include <fenv.h>
@@ -167,39 +171,30 @@ TEST(math, signbit) {
}
TEST(math, __fpclassifyd) {
-#if defined(__BIONIC__)
+#if defined(__GLIBC__)
+#define __fpclassifyd __fpclassify
+#endif
ASSERT_EQ(FP_INFINITE, __fpclassifyd(HUGE_VAL));
ASSERT_EQ(FP_NAN, __fpclassifyd(nan("")));
ASSERT_EQ(FP_NORMAL, __fpclassifyd(1.0));
ASSERT_EQ(FP_SUBNORMAL, __fpclassifyd(double_subnormal()));
ASSERT_EQ(FP_ZERO, __fpclassifyd(0.0));
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // __BIONIC__
}
TEST(math, __fpclassifyf) {
-#if defined(__BIONIC__)
ASSERT_EQ(FP_INFINITE, __fpclassifyf(HUGE_VALF));
ASSERT_EQ(FP_NAN, __fpclassifyf(nanf("")));
ASSERT_EQ(FP_NORMAL, __fpclassifyf(1.0f));
ASSERT_EQ(FP_SUBNORMAL, __fpclassifyf(float_subnormal()));
ASSERT_EQ(FP_ZERO, __fpclassifyf(0.0f));
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // __BIONIC__
}
TEST(math, __fpclassifyl) {
-#if defined(__BIONIC__)
EXPECT_EQ(FP_INFINITE, __fpclassifyl(HUGE_VALL));
EXPECT_EQ(FP_NAN, __fpclassifyl(nanl("")));
EXPECT_EQ(FP_NORMAL, __fpclassifyl(1.0L));
EXPECT_EQ(FP_SUBNORMAL, __fpclassifyl(ldouble_subnormal()));
EXPECT_EQ(FP_ZERO, __fpclassifyl(0.0L));
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // __BIONIC__
}
TEST(math, finitef) {
@@ -208,30 +203,27 @@ TEST(math, finitef) {
}
TEST(math, __isfinite) {
-#if defined(__BIONIC__)
+#if defined(__GLIBC__)
+#define __isfinite __finite
+#endif
ASSERT_TRUE(__isfinite(123.0));
ASSERT_FALSE(__isfinite(HUGE_VAL));
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // __BIONIC__
}
TEST(math, __isfinitef) {
-#if defined(__BIONIC__)
+#if defined(__GLIBC__)
+#define __isfinitef __finitef
+#endif
ASSERT_TRUE(__isfinitef(123.0f));
ASSERT_FALSE(__isfinitef(HUGE_VALF));
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // __BIONIC__
}
TEST(math, __isfinitel) {
-#if defined(__BIONIC__)
+#if defined(__GLIBC__)
+#define __isfinitel __finitel
+#endif
ASSERT_TRUE(__isfinitel(123.0L));
ASSERT_FALSE(__isfinitel(HUGE_VALL));
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // __BIONIC__
}
TEST(math, finite) {
@@ -281,7 +273,7 @@ TEST(math, __isnormal) {
ASSERT_TRUE(__isnormal(123.0));
ASSERT_FALSE(__isnormal(double_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_LOG_(INFO) << "glibc doesn't have __isnormal.\n";
#endif // __BIONIC__
}
@@ -290,7 +282,7 @@ TEST(math, __isnormalf) {
ASSERT_TRUE(__isnormalf(123.0f));
ASSERT_FALSE(__isnormalf(float_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_LOG_(INFO) << "glibc doesn't have __isnormalf.\n";
#endif // __BIONIC__
}
@@ -299,7 +291,7 @@ TEST(math, __isnormall) {
ASSERT_TRUE(__isnormall(123.0L));
ASSERT_FALSE(__isnormall(ldouble_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_LOG_(INFO) << "glibc doesn't have __isnormall.\n";
#endif // __BIONIC__
}
@@ -1156,7 +1148,7 @@ TEST(math, gamma_r) {
ASSERT_DOUBLE_EQ(log(24.0), gamma_r(5.0, &sign));
ASSERT_EQ(1, sign);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_LOG_(INFO) << "glibc doesn't have gamma_r.\n";
#endif // __BIONIC__
}
@@ -1166,7 +1158,7 @@ TEST(math, gammaf_r) {
ASSERT_FLOAT_EQ(logf(24.0f), gammaf_r(5.0f, &sign));
ASSERT_EQ(1, sign);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_LOG_(INFO) << "glibc doesn't have gammaf_r.\n";
#endif // __BIONIC__
}
@@ -1386,3 +1378,73 @@ TEST(math, nextafterl_OpenBSD_bug) {
ASSERT_TRUE(nextafterf(1.0f, 0.0f) - 1.0f < 0.0f);
ASSERT_TRUE(nextafterl(1.0L, 0.0L) - 1.0L < 0.0L);
}
+
+#include "math_cos_intel_data.h"
+TEST(math, cos_intel) {
+ DoMathDataTest<1>(g_cos_intel_data, cos);
+}
+
+#include "math_cosf_intel_data.h"
+TEST(math, cosf_intel) {
+ DoMathDataTest<1>(g_cosf_intel_data, cosf);
+}
+
+#include "math_exp_intel_data.h"
+TEST(math, exp_intel) {
+ DoMathDataTest<1>(g_exp_intel_data, exp);
+}
+
+#include "math_expf_intel_data.h"
+TEST(math, expf_intel) {
+ DoMathDataTest<1>(g_expf_intel_data, expf);
+}
+
+#include "math_log_intel_data.h"
+TEST(math, log_intel) {
+ DoMathDataTest<1>(g_log_intel_data, log);
+}
+
+#include "math_logf_intel_data.h"
+TEST(math, logf_intel) {
+ DoMathDataTest<1>(g_logf_intel_data, logf);
+}
+
+#include "math_pow_intel_data.h"
+TEST(math, pow_intel) {
+ DoMathDataTest<1>(g_pow_intel_data, pow);
+}
+
+#include "math_powf_intel_data.h"
+TEST(math, powf_intel) {
+ DoMathDataTest<1>(g_powf_intel_data, powf);
+}
+
+#include "math_sin_intel_data.h"
+TEST(math, sin_intel) {
+ DoMathDataTest<1>(g_sin_intel_data, sin);
+}
+
+#include "math_sincos_intel_data.h"
+TEST(math, sincos_intel) {
+ DoMathDataTest<1>(g_sincos_intel_data, sincos);
+}
+
+#include "math_sincosf_intel_data.h"
+TEST(math, sincosf_intel) {
+ DoMathDataTest<1>(g_sincosf_intel_data, sincosf);
+}
+
+#include "math_sinf_intel_data.h"
+TEST(math, sinf_intel) {
+ DoMathDataTest<1>(g_sinf_intel_data, sinf);
+}
+
+#include "math_tan_intel_data.h"
+TEST(math, tan_intel) {
+ DoMathDataTest<1>(g_tan_intel_data, tan);
+}
+
+#include "math_tanf_intel_data.h"
+TEST(math, tanf_intel) {
+ DoMathDataTest<1>(g_tanf_intel_data, tanf);
+}