From 477b5f688c80064753827693c16d49957d3a3a95 Mon Sep 17 00:00:00 2001 From: Mikhail Maltsev Date: Mon, 19 Feb 2018 15:41:36 +0000 Subject: [libcxx] Improve accuracy of complex asinh and acosh Summary: Currently std::asinh and std::acosh use std::pow to compute x^2. This results in a significant error when computing e.g. asinh(i) or acosh(-1). This patch expresses x^2 directly via x.real() and x.imag(), like it is done in libstdc++/glibc, and adds tests that checks the accuracy. Reviewers: EricWF, mclow.lists Reviewed By: mclow.lists Subscribers: christof, cfe-commits Differential Revision: https://reviews.llvm.org/D41629 llvm-svn: 325510 --- .../complex.number/complex.transcendentals/acosh.pass.cpp | 9 +++++++++ .../complex.number/complex.transcendentals/asinh.pass.cpp | 9 +++++++++ 2 files changed, 18 insertions(+) (limited to 'libcxx/test/std/numerics') diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp index deb056d67de..5258bdc3a0f 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp @@ -54,6 +54,15 @@ void test_edges() assert(r.imag() == 0); assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } + else if (testcases[i].real() == -1 && testcases[i].imag() == 0) + { + assert(r.real() == 0); + assert(!std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi); + else + is_about(r.imag(), pi); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp index 3da56c32f19..cb9188d935a 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp @@ -44,6 +44,15 @@ void test_edges() assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } + else if (testcases[i].real() == 0 && std::abs(testcases[i].imag()) == 1) + { + assert(r.real() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi/2); + else + is_about(r.imag(), pi/2); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { assert(std::isinf(r.real())); -- cgit v1.2.3