nuttx/libs/libc/math/lib_scalbn.c
Nathan Hartman 6b89b6f945 Remove executable permissions from source files
* arch/arm/src/sama5/sam_flexcom_spi.h,
  arch/risc-v/src/mpfs/mpfs_ihc_sbi.c,
  drivers/usbdev/adb.c,
  libs/libc/math/lib_scalbn.c,
  libs/libc/math/lib_scalbnf.c,
  net/ipfrag/Make.defs,
  net/ipfrag/ipfrag.c,
  net/ipfrag/ipfrag.h,
  net/ipfrag/ipv4_frag.c,
  net/ipfrag/ipv6_frag.c: Remove executable permission.
2023-01-30 20:34:51 -03:00

89 lines
2.2 KiB
C

/****************************************************************************
* libs/libc/math/lib_scalbn.c
* get a double number of x*2^n
*
* This file is copy from musl libc
* musl is an implementation of the C standard library built on top of the
* Linux system call API, including interfaces defined in the base language
* standard, POSIX, and widely agreed-upon extensions.
* musl is lightweight, fast, simple, free, and strives to be correct in
* the sense of standards-conformance and safety.
*
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <math.h>
#include <stdint.h>
/****************************************************************************
* Pre-processor definitions
****************************************************************************/
#ifdef CONFIG_HAVE_DOUBLE
#define DOUBLE_MIN (0x1p-1022)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: scalbn
*
* Description:
* get a double number of x*2^n
*
****************************************************************************/
double scalbn(double x, int n)
{
union
{
double f;
uint64_t i;
}u;
double_t y = x;
if (n > 1023)
{
y *= 0x1p1023;
n -= 1023;
if (n > 1023)
{
y *= 0x1p1023;
n -= 1023;
if (n > 1023)
{
n = 1023;
}
}
}
else if (n < -1022)
{
/* make sure final n < -53 to avoid double
* rounding in the subnormal range
*/
y *= DOUBLE_MIN * 0x1p53;
n += 1022 - 53;
if (n < -1022)
{
y *= DOUBLE_MIN * 0x1p53;
n += 1022 - 53;
if (n < -1022)
{
n = -1022;
}
}
}
u.i = (uint64_t)(0x3ff + n) << 52;
x = y * u.f;
return x;
}
#endif /* CONFIG_HAVE_DOUBLE */