
/*
(C) 2008-2026 Advanced Micro Devices, Inc. All Rights Reserved.

Advanced Micro Devices, Inc.
Software License Agreement

IMPORTANT-READ CAREFULLY:  Do not load or use the Software until you have
carefully read and agreed to the following terms and conditions.  This is a
legal agreement ("Agreement") between you (either an individual or an entity)
("Licensee") and Advanced Micro Devices, Inc. ("AMD"). If Licensee does not
agree to the terms of this Agreement, do not install or use this software or
any portion thereof.  By loading or using the object code version only of the
software obtained herewith, which may include associated install scripts and
online or electronic documentation or any portion thereof, that is made
available by AMD to download from any media ("Software"), Licensee agrees to
all of the terms of this Agreement.

1.  LICENSE:

    a.  Subject to the terms and conditions of this Agreement, AMD grants
    Licensee the following non-exclusive, non-transferable, royalty-free,
    limited copyright license to download, copy, use, distribute and sublicense
    the foregoing rights through multiple tiers of sublicenses the object code
    version of the Software and materials associated with this Agreement,
    including without limitation printed documentation, (collectively,
    "Materials"), provided that Licensee agrees to include all copyright
    legends and other legal notices that may appear in the Materials.  The
    foregoing license is conditioned upon Licensee distributing the object code
    version of the Software only and under this software license agreement.
    Except for the limited license granted herein, Licensee shall have no other
    rights in the Materials, whether express, implied, arising by estoppel or
    otherwise.

    b.  Except as expressly set forth in Section 1(a), Licensee does not have
    the right to (i) distribute, rent, lease, sell, sublicense, assign, or
    otherwise transfer the Materials, in whole or in part, to third parties for
    commercial or for non-commercial use; or (ii) modify, disassemble, reverse
    engineer, or decompile the Software, or otherwise reduce any part of the
    Software to any human readable form.  All rights in and to the Materials
    not expressly granted to Licensee in this Agreement are reserved to AMD.

2.  FEEDBACK:  Licensee may provide AMD feedback, suggestions or opinions as to
the Software, its features, and desired enhancements or changes.  If Licensee
provides feedback, suggestions or opinions to AMD regarding any new features,
use, functionality, or change to the Software or any materials related to the
Software, Licensee hereby agrees to grant, and does grant, AMD all rights
needed for AMD to incorporate, modify, distribute, use and commercialize any
new feature, use, functionality, or change at no charge or encumbrance to AMD.
Licensee agrees that AMD may disclose such feedback, suggestions or opinions to
any third party in any manner, and Licensee agrees that AMD has the ability to
sublicense any of the foregoing rights in any feedback, suggestions or opinions
or AMD products or services in any form to any third party without restriction.

3.  OWNERSHIP AND COPYRIGHT OF MATERIALS: Licensee agrees that the Materials
are owned by AMD and are protected by United States and foreign intellectual
property laws (e.g. patent and copyright laws) and international treaty
provisions.  Licensee will not remove the copyright notice from the Materials.
Licensee agrees to prevent any unauthorized copying of the Materials.  All
title and copyrights in and to the Materials, all copies thereof (in whole or
in part, and in any form), and all rights therein shall remain vested in AMD.
Except as expressly provided herein, AMD does not grant any express or implied
right to Licensee under AMD patents, copyrights, trademarks, or trade secret
information.

4.  WARRANTY DISCLAIMER: THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS
OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY,
NONINFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY, TITLE, OR FITNESS FOR ANY
PARTICULAR PURPOSE, OR THOSE ARISING FROM CUSTOM OF TRADE OR COURSE OF USAGE.
THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE MATERIALS REMAINS WITH
LICENSEE.  AMD DOES NOT WARRANT, GUARANTEE, OR MAKE ANY REPRESENTATIONS AS TO
THE CORRECTNESS, ACCURACY, COMPLETENESS, QUALITY, OR RELIABILITY OF THE
MATERIALS.

AMD DOES NOT WARRANT THAT OPERATION OF THE MATERIALS WILL BE UNINTERRUPTED OR
ERROR-FREE.  YOU ARE RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING
THE SOFTWARE AND ASSUME ALL RISKS ASSOCIATED WITH THE USE OF THE MATERIALS,
INCLUDING BUT NOT LIMITED TO THE RISKS OF PROGRAM ERRORS, DAMAGE TO OR LOSS OF
DATA, PROGRAMS OR EQUIPMENT, AND UNAVAILABILITY OR INTERRUPTION OF OPERATIONS.
SOME JURISDICTIONS DO NOT ALLOW FOR THE EXCLUSION OR LIMITATION OF IMPLIED
WARRANTIES, SO THE ABOVE LIMITATIONS OR EXCLUSIONS MAY NOT APPLY TO LICENSEE.

5.  LIMITATION OF LIABILITY:  IN NO EVENT SHALL AMD OR ITS DIRECTORS, OFFICERS,
EMPLOYEES AND AGENTS, ITS SUPPLIERS OR ITS LICENSORS BE LIABLE TO LICENSEE OR
ANY THIRD PARTIES IN RECEIPT OF THE MATERIALS FOR CONSEQUENTIAL, INCIDENTAL,
PUNITIVE OR SPECIAL DAMAGES, INCLUDING, BUT NOT LIMITED TO LOSS OF PROFITS,
BUSINESS INTERRUPTION, OR LOSS OF INFORMATION ARISING OUT OF THE USE OF OR
INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.  AMD DOES NOT ASSUME ANY RESPONSIBILITY TO SUPPORT OR UPDATE
THE MATERIALS.  BY USING THE MATERIALS WITHOUT CHARGE, YOU ACCEPT THIS
ALLOCATION OF RISK.  BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR
LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
LIMITATION MAY NOT APPLY TO LICENSEE.

6.  U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
"RESTRICTED RIGHTS."  Use, duplication or disclosure by the Government is
subject to restrictions as set forth in FAR52.227-14 and DFAR252.227-7013, et
seq., or its successor.  Use of the Materials by the Government constitutes
acknowledgment of AMD's proprietary rights in them.

7.  TERMINATION OF LICENSE: This Agreement will terminate immediately without
notice from AMD or judicial resolution if Licensee fails to comply with any
provisions of this Agreement.  Upon termination of this Agreement, Licensee
must delete or destroy all copies of the Materials.

8.  SUPPORT.  Under this Agreement, AMD is under no obligation to assist in the
use of the Materials, to provide support to licensees of the Materials, or to
provide maintenance, correction, modification, enhancement, or upgrades to the
Materials.  If AMD determines, in its sole discretion, to support, maintain,
correct, modify, enhance, or upgrade the Software, such support, maintenance,
correction, modification, enhancement or upgrade shall be considered part of
the Materials, and shall be subject to this Agreement.

9.  SURVIVAL:  Sections 1(b), 2, 3, 4, 5, 6, and 8 through 14 shall survive any
expiration or termination of this Agreement.

10. APPLICABLE LAWS:  Any claim arising under or relating to this Agreement
shall be governed by and construed in accordance with the substantive laws of
the State of California, without regard to principles of conflict of laws.
Each party hereto submits to the jurisdiction of the state and federal courts
of Santa Clara County and the Northern District of California for the purposes
of all legal proceedings arising out of or relating to this Agreement or the
subject matter hereof.  Each party waives any objection which it may have to
contest such forum.

11. IMPORT/EXPORT/RE-EXPORT/USE/RELEASE/TRANSFER RESTRICTIONS AND COMPLIANCE
WITH LAWS:  Licensee is hereby provided notice, and agrees and acknowledges,
that the Software, its source code, any accompanying media, material or
information, and any product of the foregoing, may be subject to restrictions
on use, release, transfer, importation, exportation and/or re- exportation
under the laws and regulations of the United States or other countries
("Applicable Laws"), which include but are not limited to U.S. export control
laws such as the Export Administration Regulations and national security
controls as defined thereunder, as well as State Department controls under the
U.S. Munitions List.  Licensee further agrees that the Software, its source
code, any accompanying media, material or information, and any product of the
foregoing, will not be used, released, transferred, imported, exported and/or
re-exported in any manner prohibited under Applicable Laws, including U.S.
export control laws regarding specifically designated persons, countries and
nationals of countries subject to national security controls as provided in
License Exception TSR of the Export Administration Regulations and any
successor regulations.

12. SEVERABILITY:  Should any term of this Agreement be declared void or
unenforceable by any court of competent jurisdiction, such declaration shall
have no effect on the remaining terms hereof.

13. NO WAIVER:  The failure of either party to enforce any rights granted
hereunder or to take action against the other party in the event of any breach
hereunder shall not be deemed a waiver by that party as to subsequent
enforcement of rights or subsequent actions in the event of future breaches.

14. ENTIRE AGREEMENT:  This Agreement constitutes the entire agreement between
the parties and supersedes any prior or contemporaneous oral or written
agreements with respect to the subject matter of this Agreement.
*/


/** @file amdlibm.h
 *  @brief AOCL-LibM header file for scaler variant.
 *
 *  This file declares the public APIs from AOCL-LibM library.
 */

#ifndef __AMDLIBM_H__
#define __AMDLIBM_H__


#include <complex.h>
#include "amdlibm_vec.h"


#if ((defined (_WIN64) || defined (_WIN32)) && defined (__clang__))
  #ifdef __cplusplus
    extern "C" {
  #endif
    /* Clang on Windows */
    typedef _C_float_complex _Fcomplex;
    typedef _C_double_complex _Dcomplex;
    typedef _C_ldouble_complex _Lcomplex;
  #ifdef __cplusplus
    }
  #endif
#endif


#if (defined (_WIN64) || defined (_WIN32))
  /* Windows */
  typedef    _Fcomplex     fc32_t;
  typedef    _Dcomplex     fc64_t;
  typedef    _Lcomplex     fc128_t;
#else
  /* Linux */
  typedef    float _Complex       fc32_t;
  typedef    double _Complex      fc64_t;
  typedef    long double _Complex fc128_t;
#endif


#ifdef __cplusplus
extern "C" {
#endif

/* Trigonometric */
  /**
   * @brief Computes the sine of a double-precision angle.
   * @param x Input angle in radians.
   * @return Sine of x.
   */
  double amd_sin (double x);
  /**
   * @brief Computes the sine of a single-precision angle.
   * @param x Input angle in radians.
   * @return Sine of x.
   */
  float amd_sinf (float x);
  
  /**
   * @brief Computes the cosine of a double-precision angle.
   * @param x Input angle in radians.
   * @return Cosine of x.
   */
  double amd_cos (double x);
  /**
   * @brief Computes the cosine of a single-precision angle.
   * @param x Input angle in radians.
   * @return Cosine of x.
   */
  float amd_cosf (float x);

  /**
   * @brief Computes the tangent of a double-precision angle.
   * @param x Input angle in radians.
   * @return Tangent of x.
   */
  double amd_tan (double x);
  /**
   * @brief Computes the tangent of a single-precision angle.
   * @param x Input angle in radians.
   * @return Tangent of x.
   */
  float amd_tanf (float x);

/* Inverse Trigonometric */
  /**
   * @brief Computes the principal value of the arc-sine of a double-precision value.
   * @param x Input value.
   * @return Arc-sine of x in radians.
   */
  double amd_asin (double x);
  /**
   * @brief Computes the principal value of the arc-sine of a single-precision value.
   * @param x Input value.
   * @return Arc-sine of x in radians.
   */
  float amd_asinf (float x);

  /**
   * @brief Computes the principal value of the arc-cosine of a double-precision value.
   * @param x Input value.
   * @return Arc-cosine of x in radians.
   */
  double amd_acos (double x);
  /**
   * @brief Computes the principal value of the arc-cosine of a single-precision value.
   * @param x Input value.
   * @return Arc-cosine of x in radians.
   */
  float amd_acosf (float x);

  /**
   * @brief Computes the principal value of the arc-tangent of a double-precision value.
   * @param x Input value.
   * @return Arc-tangent of x in radians.
   */
  double amd_atan (double x);
  /**
   * @brief Computes the principal value of the arc-tangent of a single-precision value.
   * @param x Input value.
   * @return Arc-tangent of x in radians.
   */
  float amd_atanf (float x);

  /**
   * @brief Computes the arc-tangent of the quotient of two double-precision values.
   * @param x First argument.
   * @param y Second argument.
   * @return Angle in radians, using the signs of both arguments to determine the correct quadrant.
   */
  double amd_atan2 (double x, double y);
  /**
   * @brief Computes the arc-tangent of the quotient of two single-precision values.
   * @param x First argument.
   * @param y Second argument.
   * @return Angle in radians, using the signs of both arguments to determine the correct quadrant.
   */
  float amd_atan2f (float x, float y);

  /**
   * @brief Computes both sine and cosine of a double-precision angle.
   * @param x Input angle in radians.
   * @param s Output pointer for sine of x.
   * @param c Output pointer for cosine of x.
   */
  void amd_sincos (double x, double *s, double *c);
  /**
   * @brief Computes both sine and cosine of a single-precision angle.
   * @param x Input angle in radians.
   * @param s Output pointer for sine of x.
   * @param c Output pointer for cosine of x.
   */
  void amd_sincosf (float x, float *s, float *c);

/* Hyperbolic */
  /**
   * @brief Computes the hyperbolic sine of a double-precision value.
   * @param x Input value.
   * @return Hyperbolic sine of x.
   */
  double amd_sinh (double x);
  /**
   * @brief Computes the hyperbolic sine of a single-precision value.
   * @param x Input value.
   * @return Hyperbolic sine of x.
   */
  float amd_sinhf (float x);

  /**
   * @brief Computes the hyperbolic cosine of a double-precision value.
   * @param x Input value.
   * @return Hyperbolic cosine of x.
   */
  double amd_cosh (double x);
  /**
   * @brief Computes the hyperbolic cosine of a single-precision value.
   * @param x Input value.
   * @return Hyperbolic cosine of x.
   */
  float amd_coshf (float x);

  /**
   * @brief Computes the hyperbolic tangent of a double-precision value.
   * @param x Input value.
   * @return Hyperbolic tangent of x.
   */
  double amd_tanh (double x);
  /**
   * @brief Computes the hyperbolic tangent of a single-precision value.
   * @param x Input value.
   * @return Hyperbolic tangent of x.
   */
  float amd_tanhf (float x);

/* Inverse Hyperbolic */
  /**
   * @brief Computes the inverse hyperbolic sine of a double-precision value.
   * @param x Input value.
   * @return Inverse hyperbolic sine of x.
   */
  double amd_asinh (double x);
  /**
   * @brief Computes the inverse hyperbolic sine of a single-precision value.
   * @param x Input value.
   * @return Inverse hyperbolic sine of x.
   */
  float amd_asinhf (float x);

  /**
   * @brief Computes the inverse hyperbolic cosine of a double-precision value.
   * @param x Input value.
   * @return Inverse hyperbolic cosine of x.
   */
  double amd_acosh (double x);
  /**
   * @brief Computes the inverse hyperbolic cosine of a single-precision value.
   * @param x Input value.
   * @return Inverse hyperbolic cosine of x.
   */
  float amd_acoshf (float x);
  

  /**
   * @brief Computes the inverse hyperbolic tangent of a double-precision value.
   * @param x Input value.
   * @return Inverse hyperbolic tangent of x.
   */
  double amd_atanh (double x);
  /**
   * @brief Computes the inverse hyperbolic tangent of a single-precision value.
   * @param x Input value.
   * @return Inverse hyperbolic tangent of x.
   */
  float amd_atanhf (float x);

/* Exponential */
  /**
   * @brief Computes e raised to a double-precision power.
   * @param x Exponent.
   * @return e^x.
   */
  double amd_exp (double x);
  /**
   * @brief Computes e raised to a single-precision power.
   * @param x Exponent.
   * @return e^x.
   */
  float amd_expf (float x);

  /**
   * @brief Computes 2 raised to a double-precision exponent.
   * @param x Exponent.
   * @return 2^x.
   */
  double amd_exp2 (double x);
  /**
   * @brief Computes 2 raised to a single-precision exponent.
   * @param x Exponent.
   * @return 2^x.
   */
  float amd_exp2f (float x);

  /**
   * @brief Computes 10 raised to a double-precision exponent.
   * @param x Exponent.
   * @return 10^x.
   */
  double amd_exp10 (double x);
  /**
   * @brief Computes 10 raised to a single-precision exponent.
   * @param x Exponent.
   * @return 10^x.
   */
  float amd_exp10f (float x);

  /**
   * @brief Computes exp(x) - 1 with reduced error for small x (double-precision).
   * @param x Input value.
   * @return exp(x) - 1.
   */
  double amd_expm1 (double x);
  /**
   * @brief Computes exp(x) - 1 with reduced error for small x (single-precision).
   * @param x Input value.
   * @return exp(x) - 1.
   */
  float amd_expm1f (float x);

/* Logarithmic */
  /**
   * @brief Computes the natural logarithm (base e) of a double-precision value.
   * @param x Input value.
   * @return Natural logarithm of x.
   */
  double amd_log (double x);
  /**
   * @brief Computes the natural logarithm (base e) of a single-precision value.
   * @param x Input value.
   * @return Natural logarithm of x.
   */
  float amd_logf (float x);

  /**
   * @brief Computes the base-2 logarithm of a double-precision value.
   * @param x Input value.
   * @return Base-2 logarithm of x.
   */
  double amd_log2 (double x);
  /**
   * @brief Computes the base-2 logarithm of a single-precision value.
   * @param x Input value.
   * @return Base-2 logarithm of x.
   */
  float amd_log2f (float x);

  /**
   * @brief Computes the base-10 logarithm of a double-precision value.
   * @param x Input value.
   * @return Base-10 logarithm of x.
   */
  double amd_log10 (double x);
  /**
   * @brief Computes the base-10 logarithm of a single-precision value.
   * @param x Input value.
   * @return Base-10 logarithm of x.
   */
  float amd_log10f (float x);

  /**
   * @brief Computes log(1 + x) with reduced error for small x (double-precision).
   * @param x Input value.
   * @return log(1 + x).
   */
  double amd_log1p (double x);
  /**
   * @brief Computes log(1 + x) with reduced error for small x (single-precision).
   * @param x Input value.
   * @return log(1 + x).
   */
  float amd_log1pf (float x);

/* Power & Root */
  /**
   * @brief Computes the result of raising a double-precision base to a double-precision exponent.
   * @param x Base.
   * @param y Exponent.
   * @return x raised to the power y.
   */
  double amd_pow (double x, double y);
  /**
   * @brief Computes the result of raising a single-precision base to a single-precision exponent..
   * @param x Base.
   * @param y Exponent.
   * @return x raised to the power y.
   */
  float amd_powf (float x, float y);

  /**
   * @brief Computes the square root of a double-precision value.
   * @param x Input value.
   * @return Square root of x.
   */
  double amd_sqrt (double x);
  /**
   * @brief Computes the square root of a single-precision value.
   * @param x Input value.
   * @return Square root of x.
   */
  float amd_sqrtf (float x);

  /**
   * @brief Computes the cube root of a double-precision value.
   * @param x Input value.
   * @return Cube root of x.
   */
  double amd_cbrt (double x);
  /**
   * @brief Computes the cube root of a single-precision value.
   * @param x Input value.
   * @return Cube root of x.
   */
  float amd_cbrtf (float x);

/* Error */
  /**
   * @brief Computes the Gaussian error function for a double-precision value.
   * @param x Input value.
   * @return erf(x).
   */
  double amd_erf (double x);
  /**
   * @brief Computes the Gaussian error function for a single-precision value.
   * @param x Input value.
   * @return erf(x).
   */
  float amd_erff (float x);

/* Inverse Error */
  /**
   * @brief Computes the Gaussian inverse error function for a double-precision value.
   * @param x Input value.
   * @return erfinv(x).
   */
  double amd_erfinv (double x);

/* Complementary Error */
  /**
   * @brief Computes the complementary error function for a double-precision value.
   * @param x Input value.
   * @return erfc(x).
   */
  double amd_erfc (double x);
  /**
   * @brief Computes the complementary error function for a single-precision value.
   * @param x Input value.
   * @return erfcf(x).
   */
  float amd_erfcf (float x);

/* Special */
  /**
   * @brief Computes the cumulative normal distribution function values of a double-precision value
   * @param x Input value.
   * @return cdfnorm(x).
   */
  double amd_cdfnorm (double x);

  /**
   * @brief Computes the inverse cumulative normal distribution function
   * @param x Input value.
   * @return cdfnorminv(x).
   */
  double amd_cdfnorminv (double x);

  /* Inverse Complementary Error */
  /**
   * @brief Computes the inverse complementary error function for a double-precision value.
   * @param x Input value.
   * @return erfcinv(x).
   */
  double amd_erfcinv (double x);

/* Remainder */
  /**
   * @brief Computes the remainder of the division operation x/y (double-precision).
   * @param x Numerator.
   * @param y Denominator.
   * @return Remainder of x divided by y.
   */
  double amd_fmod (double x, double y);
  /**
   * @brief Computes the remainder of the division operation x/y (single-precision).
   * @param x Numerator.
   * @param y Denominator.
   * @return Remainder of x divided by y.
   */
  float amd_fmodf (float x, float y);

  /**
   * @brief Computes the IEEE 754-style remainder of x with respect to y (double-precision).
   * @param x Numerator.
   * @param y Denominator.
   * @return Remainder value.
   */
  double amd_remainder (double x, double y);
  /**
   * @brief Computes the IEEE 754-style remainder of x with respect to y (single-precision).
   * @param x Numerator.
   * @param y Denominator.
   * @return Remainder value.
   */
  float amd_remainderf (float x, float y);

  /**
   * @brief Computes the remainder and part of the quotient for double-precision inputs.
   * @param x Numerator.
   * @param y Denominator.
   * @param quo Output pointer receiving a part of the quotient.
   * @return Remainder value.
   */
  double amd_remquo (double x, double y, int *quo);
  /**
   * @brief Computes the remainder and part of the quotient for single-precision inputs.
   * @param x Numerator.
   * @param y Denominator.
   * @param quo Output pointer receiving a part of the quotient.
   * @return Remainder value.
   */
  float amd_remquof (float x, float y, int *quo);

/* Maximum, Minimum & Difference */
  /**
   * @brief Returns the larger of two double-precision values.
   * @param x First value.
   * @param y Second value.
   * @return Maximum of x and y.
   */
  double amd_fmax  (double x, double y);
  /**
   * @brief Returns the larger of two single-precision values.
   * @param x First value.
   * @param y Second value.
   * @return Maximum of x and y.
   */
  float amd_fmaxf (float x, float y);

  /**
   * @brief Returns the smaller of two double-precision values.
   * @param x First value.
   * @param y Second value.
   * @return Minimum of x and y.
   */
  double amd_fmin (double x, double y);
  /**
   * @brief Returns the smaller of two single-precision values.
   * @param x First value.
   * @param y Second value.
   * @return Minimum of x and y.
   */
  float amd_fminf (float x, float y);

  /**
   * @brief Computes the positive difference max(x - y, 0) for double-precision values.
   * @param x Minuend.
   * @param y Subtrahend.
   * @return Positive difference.
   */
  double amd_fdim (double x, double y);
  /**
   * @brief Computes the positive difference max(x - y, 0) for single-precision values.
   * @param x Minuend.
   * @param y Subtrahend.
   * @return Positive difference.
   */
  float amd_fdimf (float x, float y);

/* Euclidean Distance */
  /**
   * @brief Computes sqrt(x^2 + y^2) for two double-precision inputs.
   * @param x First value.
   * @param y Second value.
   * @return Euclidean norm of (x, y).
   */
  double amd_hypot (double x, double y);
  /**
   * @brief Computes sqrt(x^2 + y^2) for two single-precision inputs.
   * @param x First value.
   * @param y Second value.
   * @return Euclidean norm of (x, y).
   */
  float amd_hypotf (float x, float y);

/* Nearest Integer */
  /**
   * @brief Rounds a double-precision value upward to the nearest integer value.
   * @param x Input value.
   * @return Smallest integer value not less than x.
   */
  double amd_ceil (double x);
  /**
   * @brief Rounds a single-precision value upward to the nearest integer value.
   * @param x Input value.
   * @return Smallest integer value not less than x.
   */
  float amd_ceilf (float x);

  /**
   * @brief Rounds a double-precision value downward to the nearest integer value.
   * @param x Input value.
   * @return Largest integer value not greater than x.
   */
  double amd_floor (double x);
  /**
   * @brief Rounds a single-precision value downward to the nearest integer value.
   * @param x Input value.
   * @return Largest integer value not greater than x.
   */
  float amd_floorf (float x);

  /**
   * @brief Truncates a double-precision value toward zero.
   * @param x Input value.
   * @return Truncated integer value as double.
   */
  double amd_trunc (double x);
  /**
   * @brief Truncates a single-precision value toward zero.
   * @param x Input value.
   * @return Truncated integer value as float.
   */
  float amd_truncf (float x);

  /**
   * @brief Rounds a double-precision value to an integer value according to current rounding mode.
   * @param x Input value.
   * @return Rounded value.
   */
  double amd_nearbyint (double x);
  /**
   * @brief Rounds a single-precision value to an integer value according to current rounding mode.
   * @param x Input value.
   * @return Rounded value.
   */
  float amd_nearbyintf (float x);

  /**
   * @brief Rounds a double-precision value to an integer value according to current rounding mode, as double.
   * @param x Input value.
   * @return Rounded value.
   */
  double amd_rint (double x);
  /**
   * @brief Rounds a single-precision value to an integer value according to current rounding mode, as float.
   * @param x Input value.
   * @return Rounded value.
   */
  float amd_rintf (float x);

  /**
   * @brief Rounds a double-precision value to a long int according to current rounding mode.
   * @param x Input value.
   * @return Rounded long int.
   */
  long int amd_lrint (double x);
  /**
   * @brief Rounds a single-precision value to a long int according to current rounding mode.
   * @param x Input value.
   * @return Rounded long int.
   */
  long int amd_lrintf (float x);

  /**
   * @brief Rounds a double-precision value to a long long int according to current rounding mode.
   * @param x Input value.
   * @return Rounded long long int.
   */
  long long int amd_llrint (double x);
  /**
   * @brief Rounds a single-precision value to a long long int according to current rounding mode.
   * @param x Input value.
   * @return Rounded long long int.
   */
  long long int amd_llrintf (float x);

  /**
   * @brief Rounds a double-precision value to the nearest integer, halfway cases away from zero.
   * @param f Input value.
   * @return Rounded value.
   */
  double amd_round (double f);
  /**
   * @brief Rounds a single-precision value to the nearest integer, halfway cases away from zero.
   * @param f Input value.
   * @return Rounded value.
   */
  float amd_roundf (float f);

  /**
   * @brief Rounds a double-precision value to the nearest integer and returns it as long int.
   * @param d Input value.
   * @return Rounded long int.
   */
  long int amd_lround (double d);
  /**
   * @brief Rounds a single-precision value to the nearest integer and returns it as long int.
   * @param f Input value.
   * @return Rounded long int.
   */
  long int amd_lroundf (float f);

  /**
   * @brief Rounds a double-precision value to the nearest integer and returns it as long long int.
   * @param d Input value.
   * @return Rounded long long int.
   */
  long long int amd_llround (double d);
  /**
   * @brief Rounds a single-precision value to the nearest integer and returns it as long long int.
   * @param f Input value.
   * @return Rounded long long int.
   */
  long long int amd_llroundf (float f);

/* Foating-Point Manipulation */
  /**
   * @brief Computes the absolute value of a double-precision number.
   * @param x Input value.
   * @return |x|.
   */
  double amd_fabs (double x);
  /**
   * @brief Computes the absolute value of a single-precision number.
   * @param x Input value.
   * @return |x|.
   */
  float amd_fabsf (float x);

  /**
   * @brief Decomposes a double-precision number into fractional and integer parts.
   * @param x Input value.
   * @param iptr Output pointer to receive integer part.
   * @return Fractional part of x.
   */
  double amd_modf (double x, double *iptr);
  /**
   * @brief Decomposes a single-precision number into fractional and integer parts.
   * @param x Input value.
   * @param iptr Output pointer to receive integer part.
   * @return Fractional part of x.
   */
  float amd_modff (float x, float *iptr);

  /**
   * @brief Decomposes a double-precision value into normalized fraction and exponent.
   * @param value Input value.
   * @param exp Output pointer to receive exponent.
   * @return Normalized fraction.
   */
  double amd_frexp (double value, int *exp);
  /**
   * @brief Decomposes a single-precision value into normalized fraction and exponent.
   * @param value Input value.
   * @param exp Output pointer to receive exponent.
   * @return Normalized fraction.
   */
  float amd_frexpf (float value, int *exp);

  /**
   * @brief Produces a value with the magnitude of x and the sign of y (double-precision).
   * @param x Magnitude source.
   * @param y Sign source.
   * @return Value with magnitude of x and sign of y.
   */
  double amd_copysign (double x, double y);
  /**
   * @brief Produces a value with the magnitude of x and the sign of y (single-precision).
   * @param x Magnitude source.
   * @param y Sign source.
   * @return Value with magnitude of x and sign of y.
   */
  float amd_copysignf (float x, float y);

  /**
   * @brief Generates a quiet NaN (double-precision) with an optional tag.
   * @param tagp Implementation-defined tag string.
   * @return Quiet NaN.
   */
  double amd_nan (const char *tagp);
  /**
   * @brief Generates a quiet NaN (single-precision) with an optional tag.
   * @param tagp Implementation-defined tag string.
   * @return Quiet NaN.
   */
  float amd_nanf (const char *tagp);

  /**
   * @brief Tests if a double-precision value is finite (not infinite or NaN).
   * @param x Input value.
   * @return Non-zero if finite, zero otherwise.
   */
  int amd_finite (double x);
  /**
   * @brief Tests if a single-precision value is finite (not infinite or NaN).
   * @param x Input value.
   * @return Non-zero if finite, zero otherwise.
   */
  int amd_finitef (float x);

  /**
   * @brief Multiplies a double-precision floating-point number by 2 raised to exp.
   * @param x Input value.
   * @param exp Exponent of two.
   * @return x * 2^exp.
   */
  double amd_ldexp (double x, int exp);
  /**
   * @brief Multiplies a single-precision floating-point number by 2 raised to exp.
   * @param x Input value.
   * @param exp Exponent of two.
   * @return x * 2^exp.
   */
  float amd_ldexpf (float x, int exp);

  /**
   * @brief Multiplies a double-precision value by 2 raised to n, using integer scaling.
   * @param x Input value.
   * @param n Integer scale.
   * @return x * 2^n.
   */
  double amd_scalbn (double x, int n);
  /**
   * @brief Multiplies a single-precision value by 2 raised to n, using integer scaling.
   * @param x Input value.
   * @param n Integer scale.
   * @return x * 2^n.
   */
  float amd_scalbnf (float x, int n);

  /**
   * @brief Multiplies a double-precision value by 2 raised to n, long integer scale.
   * @param x Input value.
   * @param n Long integer scale.
   * @return x * 2^n.
   */
  double amd_scalbln (double x, long int n);
  /**
   * @brief Multiplies a single-precision value by 2 raised to n, long integer scale.
   * @param x Input value.
   * @param n Long integer scale.
   * @return x * 2^n.
   */
  float amd_scalblnf (float x, long int n);

  /**
   * @brief Extracts the exponent of a double-precision floating-point value.
   * @param x Input value.
   * @return Exponent as double.
   */
  double amd_logb (double x);
  /**
   * @brief Extracts the exponent of a single-precision floating-point value.
   * @param x Input value.
   * @return Exponent as float.
   */
  float amd_logbf (float x);

  /**
   * @brief Returns the integer exponent of a double-precision value.
   * @param x Input value.
   * @return Integer exponent.
   */
  int amd_ilogb (double x);
  /**
   * @brief Returns the integer exponent of a single-precision value.
   * @param x Input value.
   * @return Integer exponent.
   */
  int amd_ilogbf (float x);

  /**
   * @brief Returns the next representable double after x in the direction of y.
   * @param x Starting value.
   * @param y Direction target.
   * @return Next representable value from x toward y.
   */
  double amd_nextafter (double x, double y);
  /**
   * @brief Returns the next representable float after x in the direction of y.
   * @param x Starting value.
   * @param y Direction target.
   * @return Next representable value from x toward y.
   */
  float amd_nextafterf (float x, float y);

  /**
   * @brief Returns the next representable double after x toward long double y.
   * @param x Starting value.
   * @param y Direction target (long double).
   * @return Next representable value from x toward y.
   */
  double amd_nexttoward (double x, long double y);
  /**
   * @brief Returns the next representable float after x toward long double y.
   * @param x Starting value.
   * @param y Direction target (long double).
   * @return Next representable value from x toward y.
   */
  float amd_nexttowardf (float x, long double y);

/* Complex Variants */
  /**
   * @brief Computes the complex exponential of a double-precision complex value.
   * @param x Input complex value.
   * @return Complex exponential of x.
   */
  fc64_t amd_cexp (fc64_t x);
  /**
   * @brief Computes the complex exponential of a single-precision complex value.
   * @param y Input complex value.
   * @return Complex exponential of y.
   */
  fc32_t amd_cexpf (fc32_t y);

  /**
   * @brief Computes the complex natural logarithm of a double-precision complex value.
   * @param x Input complex value.
   * @return Complex natural logarithm of x.
   */
  fc64_t amd_clog (fc64_t x);
  /**
   * @brief Computes the complex natural logarithm of a single-precision complex value.
   * @param y Input complex value.
   * @return Complex natural logarithm of y.
   */
  fc32_t amd_clogf (fc32_t y);

  /**
   * @brief Raises a double-precision complex base to a double-precision complex exponent.
   * @param x Complex base.
   * @param y Complex exponent.
   * @return x raised to the power y.
   */
  fc64_t amd_cpow (fc64_t x, fc64_t y);
  /**
   * @brief Raises a single-precision complex base to a single-precision complex exponent.
   * @param x Complex base.
   * @param y Complex exponent.
   * @return x raised to the power y.
   */
  fc32_t amd_cpowf (fc32_t x, fc32_t y);

#ifdef __cplusplus
}
#endif


/*
 *  Standard Math API symbols can be replaced by respective
 *  AOCL-LibM API symbols by enabling flag REPLACE_WITH_AMDLIBM.
 *  This replacement is always enabled for MSVC Compiler.
 */
#if defined (REPLACE_WITH_AMDLIBM) \
      || (defined (_MSC_VER) && !defined (__clang__))

/* Trigonometric */
  #undef sin
  #define sin amd_sin
  #undef sinf
  #define sinf amd_sinf

  #undef cos
  #define cos amd_cos
  #undef cosf
  #define cosf amd_cosf

  #undef tan
  #define tan amd_tan
  #undef tanf
  #define tanf amd_tanf

  #undef sincos
  #define sincos amd_sincos
  #undef sincosf
  #define sincosf amd_sincosf

/* Inverse Trigonometric */
  #undef asin
  #define asin amd_asin
  #undef asinf
  #define asinf amd_asinf

  #undef acos
  #define acos amd_acos
  #undef acosf
  #define acosf amd_acosf

  #undef atan
  #define atan amd_atan
  #undef atanf
  #define atanf amd_atanf

  #undef atan2
  #define atan2 amd_atan2
  #undef atan2f
  #define atan2f amd_atan2f

/* Hyperbolic */
  #undef sinh
  #define sinh amd_sinh
  #undef sinhf
  #define sinhf amd_sinhf

  #undef cosh
  #define cosh amd_cosh
  #undef coshf
  #define coshf amd_coshf

  #undef tanh
  #define tanh amd_tanh
  #undef tanhf
  #define tanhf amd_tanhf

/* Inverse Hyperbolic */
  #undef asinh
  #define asinh amd_asinh
  #undef asinhf
  #define asinhf amd_asinhf

  #undef acosh
  #define acosh amd_acosh
  #undef acoshf
  #define acoshf amd_acoshf

  #undef atanh
  #define atanh amd_atanh
  #undef atanhf
  #define atanhf amd_atanhf

/* Exponential */
  #undef exp
  #define exp amd_exp
  #undef expf
  #define expf amd_expf

  #undef exp2
  #define exp2 amd_exp2
  #undef exp2f
  #define exp2f amd_exp2f

  #undef exp10
  #define exp10 amd_exp10
  #undef exp10f
  #define exp10f amd_exp10f

  #undef expm1
  #define expm1 amd_expm1
  #undef expm1f
  #define expm1f amd_expm1f

/* Logarithmic */
  #undef log
  #define log amd_log
  #undef logf
  #define logf amd_logf

  #undef log2
  #define log2 amd_log2
  #undef log2f
  #define log2f amd_log2f

  #undef log10
  #define log10 amd_log10
  #undef log10f
  #define log10f amd_log10f

  #undef log1p
  #define log1p amd_log1p
  #undef log1pf
  #define log1pf amd_log1pf

/* Power & Root */
  #undef pow
  #define pow amd_pow
  #undef powf
  #define powf amd_powf

  #undef sqrt
  #define sqrt amd_sqrt
  #undef sqrtf
  #define sqrtf amd_sqrtf

  #undef cbrt
  #define cbrt amd_cbrt
  #undef cbrtf
  #define cbrtf amd_cbrtf

/* Error */
  #undef erf
  #define erf amd_erf
  #undef erff
  #define erff amd_erff

/* Inverse Error */
  #undef erfinv
  #define erfinv amd_erfinv

/* Complementary Error */
  #undef erfc
  #define erfc amd_erfc
  #undef erfcf
  #define erfcf amd_erfcf

/* Inverse Complementary Error */
  #undef erfcinv
  #define erfcinv amd_erfcinv
  
/* Special */
  #undef cdfnorm
  #define cdfnorm amd_cdfnorm

  #undef cdfnorminv
  #define cdfnorminv amd_cdfnorminv

/* Remainder */
  #undef fmod
  #define fmod amd_fmod
  #undef fmodf
  #define fmodf amd_fmodf

  #undef remainder
  #define remainder amd_remainder
  #undef remainderf
  #define remainderf amd_remainderf

  #undef remquo
  #define remquo amd_remquo
  #undef remquof
  #define remquof amd_remquof

/* Maximum, Minimum & Difference */
  #undef fmax
  #define fmax amd_fmax
  #undef fmaxf
  #define fmaxf amd_fmaxf

  #undef fmin
  #define fmin amd_fmin
  #undef fminf
  #define fminf amd_fminf

  #undef fdim
  #define fdim amd_fdim
  #undef fdimf
  #define fdimf amd_fdimf

/* Euclidean Distance */
  #undef _hypot
  #define _hypot amd_hypot
  #undef _hypotf
  #define _hypotf amd_hypotf

  #undef hypot
  #define hypot amd_hypot
  #undef hypotf
  #define hypotf amd_hypotf

/* Nearest Integer */
  #undef ceil
  #define ceil amd_ceil
  #undef ceilf
  #define ceilf amd_ceilf

  #undef floor
  #define floor amd_floor
  #undef floorf
  #define floorf amd_floorf

  #undef trunc
  #define trunc amd_trunc
  #undef truncf
  #define truncf amd_truncf

  #undef nearbyint
  #define nearbyint amd_nearbyint
  #undef nearbyintf
  #define nearbyintf amd_nearbyintf

  #undef rint
  #define rint amd_rint
  #undef rintf
  #define rintf amd_rintf

  #undef lrint
  #define lrint amd_lrint
  #undef lrintf
  #define lrintf amd_lrintf

  #undef llrint
  #define llrint amd_llrint
  #undef llrintf
  #define llrintf amd_llrintf

  #undef round
  #define round amd_round
  #undef roundf
  #define roundf amd_roundf

  #undef lround
  #define lround amd_lround
  #undef lroundf
  #define lroundf amd_lroundf

  #undef llround
  #define llround amd_llround
  #undef llroundf
  #define llroundf amd_llroundf

/* Floating-Point Manipulation */
  #undef fabs
  #define fabs amd_fabs
  #undef fabsf
  #define fabsf amd_fabsf

  #undef modf
  #define modf amd_modf
  #undef modff
  #define modff amd_modff

  #undef frexp
  #define frexp amd_frexp
  #undef frexpf
  #define frexpf amd_frexpf

  #undef _copysign
  #define _copysign amd_copysign
  #undef _copysignf
  #define _copysignf amd_copysignf

  #undef copysign
  #define copysign amd_copysign
  #undef copysignf
  #define copysignf amd_copysignf

  #undef nan
  #define nan amd_nan
  #undef nanf
  #define nanf amd_nanf

  #undef _finite
  #define _finite amd_finite
  #undef _finitef
  #define _finitef amd_finitef

  #undef finite
  #define finite amd_finite
  #undef finitef
  #define finitef amd_finitef

  #undef ldexp
  #define ldexp amd_ldexp
  #undef ldexpf
  #define ldexpf amd_ldexpf

  #undef scalbn
  #define scalbn amd_scalbn
  #undef scalbnf
  #define scalbnf amd_scalbnf

  #undef scalbln
  #define scalbln amd_scalbln
  #undef scalblnf
  #define scalblnf amd_scalblnf

  #undef _logb
  #define _logb amd_logb
  #undef _logbf
  #define _logbf amd_logbf

  #undef logb
  #define logb amd_logb
  #undef logbf
  #define logbf amd_logbf

  #undef ilogb
  #define ilogb amd_ilogb
  #undef ilogbf
  #define ilogbf amd_ilogbf

  #undef nextafter
  #define nextafter amd_nextafter
  #undef nextafterf
  #define nextafterf amd_nextafterf

  #undef nexttoward
  #define nexttoward amd_nexttoward
  #undef nexttowardf
  #define nexttowardf amd_nexttowardf

/* Complex Variant */
  #undef cexp
  #define cexp amd_cexp
  #undef cexpf
  #define cexpf amd_cexpf

#endif /* REPLACE_WITH_AMDLIBM */


#endif /* __AMDLIBM_H__ */
