/** * This file has no copyright assigned and is placed in the Public Domain. * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #include #include typedef union ieee754_double_ { struct __attribute__((__packed__)) { uint64_t f52 : 52; uint64_t exp : 11; uint64_t sgn : 1; }; double f; } ieee754_double; typedef union ieee754_float_ { struct __attribute__((__packed__)) { uint32_t f23 : 23; uint32_t exp : 8; uint32_t sgn : 1; }; float f; } ieee754_float; double log2(double x) { ieee754_double u = { .f = x }; if (u.sgn == 0 && u.f52 == 0 && u.exp > 0 && u.exp < 0x7ff) { // Handle exact powers of two exactly return (int)u.exp - 1023; } return log(x) / 0.69314718246459960938; } float log2f(float x) { ieee754_float u = { .f = x }; if (u.sgn == 0 && u.f23 == 0 && u.exp > 0 && u.exp < 0xff) { // Handle exact powers of two exactly return (int)u.exp - 127; } return logf(x) / 0.69314718246459960938f; } long double log2l(long double x) { #if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) return log2(x); #else #error Not supported on your platform yet #endif }