mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-22 16:37:40 +08:00

Use std::nextafter() instead of std::nexttoward() in midpoint tests. In the context of this test, this should not cause any difference. Since nexttowardl() is not implemented on NetBSD 8, the latter function combined with 'long double' type caused test failure. nextafterl() does not have this problem. Differential Revision: https://reviews.llvm.org/D61748 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@360673 91177308-0d34-0410-b5e6-96231b3b80d8
114 lines
3.7 KiB
C++
114 lines
3.7 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
|
|
// <numeric>
|
|
|
|
// template <class _Float>
|
|
// _Tp midpoint(_Float __a, _Float __b) noexcept
|
|
//
|
|
|
|
#include <numeric>
|
|
#include <cassert>
|
|
|
|
#include "test_macros.h"
|
|
#include "fp_compare.h"
|
|
|
|
// Totally arbitrary picks for precision
|
|
template <typename T>
|
|
constexpr T fp_error_pct();
|
|
|
|
template <>
|
|
constexpr float fp_error_pct<float>() { return 1.0e-4f; }
|
|
|
|
template <>
|
|
constexpr double fp_error_pct<double>() { return 1.0e-12; }
|
|
|
|
template <>
|
|
constexpr long double fp_error_pct<long double>() { return 1.0e-13l; }
|
|
|
|
|
|
template <typename T>
|
|
void fp_test()
|
|
{
|
|
ASSERT_SAME_TYPE(T, decltype(std::midpoint(T(), T())));
|
|
ASSERT_NOEXCEPT( std::midpoint(T(), T()));
|
|
|
|
constexpr T maxV = std::numeric_limits<T>::max();
|
|
constexpr T minV = std::numeric_limits<T>::min();
|
|
|
|
// Things that can be compared exactly
|
|
assert((std::midpoint(T(0), T(0)) == T(0)));
|
|
assert((std::midpoint(T(2), T(4)) == T(3)));
|
|
assert((std::midpoint(T(4), T(2)) == T(3)));
|
|
assert((std::midpoint(T(3), T(4)) == T(3.5)));
|
|
assert((std::midpoint(T(0), T(0.4)) == T(0.2)));
|
|
|
|
// Things that can't be compared exactly
|
|
constexpr T pct = fp_error_pct<T>();
|
|
assert((fptest_close_pct(std::midpoint(T( 1.3), T(11.4)), T( 6.35), pct)));
|
|
assert((fptest_close_pct(std::midpoint(T(11.33), T(31.45)), T(21.39), pct)));
|
|
assert((fptest_close_pct(std::midpoint(T(-1.3), T(11.4)), T( 5.05), pct)));
|
|
assert((fptest_close_pct(std::midpoint(T(11.4), T(-1.3)), T( 5.05), pct)));
|
|
assert((fptest_close_pct(std::midpoint(T(0.1), T(0.4)), T(0.25), pct)));
|
|
|
|
assert((fptest_close_pct(std::midpoint(T(11.2345), T(14.5432)), T(12.88885), pct)));
|
|
|
|
// From e to pi
|
|
assert((fptest_close_pct(std::midpoint(T(2.71828182845904523536028747135266249775724709369995),
|
|
T(3.14159265358979323846264338327950288419716939937510)),
|
|
T(2.92993724102441923691146542731608269097720824653752), pct)));
|
|
|
|
assert((fptest_close_pct(std::midpoint(maxV, T(0)), maxV/2, pct)));
|
|
assert((fptest_close_pct(std::midpoint(T(0), maxV), maxV/2, pct)));
|
|
assert((fptest_close_pct(std::midpoint(minV, T(0)), minV/2, pct)));
|
|
assert((fptest_close_pct(std::midpoint(T(0), minV), minV/2, pct)));
|
|
assert((fptest_close_pct(std::midpoint(maxV, maxV), maxV, pct)));
|
|
assert((fptest_close_pct(std::midpoint(minV, minV), minV, pct)));
|
|
|
|
// Denormalized values
|
|
// TODO
|
|
|
|
// Check two values "close to each other"
|
|
T d1 = 3.14;
|
|
T d0 = std::nextafter(d1, T(2));
|
|
T d2 = std::nextafter(d1, T(5));
|
|
assert(d0 < d1); // sanity checking
|
|
assert(d1 < d2); // sanity checking
|
|
|
|
// Since there's nothing in between, the midpoint has to be one or the other
|
|
T res;
|
|
res = std::midpoint(d0, d1);
|
|
assert(res == d0 || res == d1);
|
|
assert(d0 <= res);
|
|
assert(res <= d1);
|
|
res = std::midpoint(d1, d0);
|
|
assert(res == d0 || res == d1);
|
|
assert(d0 <= res);
|
|
assert(res <= d1);
|
|
|
|
res = std::midpoint(d1, d2);
|
|
assert(res == d1 || res == d2);
|
|
assert(d1 <= res);
|
|
assert(res <= d2);
|
|
res = std::midpoint(d2, d1);
|
|
assert(res == d1 || res == d2);
|
|
assert(d1 <= res);
|
|
assert(res <= d2);
|
|
}
|
|
|
|
|
|
int main (int, char**)
|
|
{
|
|
fp_test<float>();
|
|
fp_test<double>();
|
|
fp_test<long double>();
|
|
|
|
return 0;
|
|
}
|