Path: blob/main/contrib/arm-optimized-routines/math/aarch64/experimental/acoshf_2u8.c
48375 views
/*1* Single-precision acosh(x) function.2*3* Copyright (c) 2022-2024, Arm Limited.4* SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception5*/67#include "math_config.h"8#include "test_sig.h"9#include "test_defs.h"1011#define Ln2 (0x1.62e4p-1f)12#define MinusZero 0x8000000013#define SquareLim 0x5f800000 /* asuint(0x1p64). */14#define Two 0x400000001516/* acoshf approximation using a variety of approaches on different intervals:1718x >= 2^64: We cannot square x without overflow. For huge x, sqrt(x*x - 1) is19close enough to x that we can calculate the result by ln(2x) == ln(x) +20ln(2). The greatest error in the region is 0.94 ULP:21acoshf(0x1.15f706p+92) got 0x1.022e14p+6 want 0x1.022e16p+6.2223x > 2: Calculate the result directly using definition of asinh(x) = ln(x +24sqrt(x*x - 1)). Greatest error in this region is 1.30 ULP:25acoshf(0x1.249d8p+1) got 0x1.77e1aep+0 want 0x1.77e1bp+0.26270 <= x <= 2: Calculate the result using log1p. For x < 1, acosh(x) is28undefined. For 1 <= x <= 2, the greatest error is 2.78 ULP:29acoshf(0x1.07887p+0) got 0x1.ef9e9cp-3 want 0x1.ef9ea2p-3. */30float31acoshf (float x)32{33uint32_t ix = asuint (x);3435if (unlikely (ix >= MinusZero))36return __math_invalidf (x);3738if (unlikely (ix >= SquareLim))39return logf (x) + Ln2;4041if (ix > Two)42return logf (x + sqrtf (x * x - 1));4344float xm1 = x - 1;45return log1pf (xm1 + sqrtf (2 * xm1 + xm1 * xm1));46}4748TEST_SIG (S, F, 1, acosh, 1.0, 10.0)49TEST_ULP (acoshf, 2.30)50TEST_INTERVAL (acoshf, 0, 1, 100)51TEST_INTERVAL (acoshf, 1, 2, 10000)52TEST_INTERVAL (acoshf, 2, 0x1p64, 100000)53TEST_INTERVAL (acoshf, 0x1p64, inf, 100000)54TEST_INTERVAL (acoshf, -0, -inf, 10000)555657