22#ifndef PQ_FAST_MATH_H_
23#define PQ_FAST_MATH_H_
25#include "pq_globals.h"
26#include "pq_fixed32_trig.h"
35inline float fastSqrt(
const float& n)
37 static union {int32_t i;
float f;} u;
38 u.i = 0x2035AD0C + (*(int32_t*)&n >> 1);
39 return n / u.f + u.f * 0.25f;
42inline float fastSin(
float x) {
43#if defined(PQ_ARCH_32BITS)
44 x = wrap01(x/TWO_PI) * 4294967295ULL;
45 return sin32( (uint32_t)x ) / 2147483532.0f;
47 x = wrap01(x/TWO_PI) * 65535;
48 return sin16( (uint16_t)x ) / 32767.0f;
52inline float fastCos(
float x) {
53 return fastSin(HALF_PI - x);
57inline double fastPow(
double a,
double b) {
62 u.x[1] = (int32_t)(b * (u.x[1] - 1072632447) + 1072632447);
67inline float fastPow(
float a,
float b) {
68 return (
float)fastPow((
double)a, (
double)b);
73inline double fastPow2(
double b) {
79 u.x[1] = (int32_t)(b * (1 << 20) + (1023 << 20));
83inline float fastPow2(
float b) {
84 return (
float)fastPow2((
double)b);
91inline float fastLog(
float x) {
92 union {
float f; uint32_t u; } pun = { x };
94 return (
float)pun.u * (0.693147f / (float)(1 << 23)) - 88.029691f;
104inline float fastLog01(
float x) {
105 union {
float f; uint32_t u; } pun = { x };
108 int32_t k = (int32_t)(pun.u >> 23) - 127;
111 pun.u = (pun.u & 0x007FFFFF) | 0x3F800000;
114 float s = (pun.f - 1.0f) / (pun.f + 1.0f);
116 float logm = s * (2.0f + (2.0f / 3.0f) * s2);
118 return (
float)k * 0.693147f + logm;
127inline float fastNegLog32(uint32_t r) {
128 if (r == 0)
return 32.0f * 0.693147f;
130 const uint32_t z = __builtin_clz(r);
135 union {
float f; uint32_t u; } pun;
136 pun.u = ((r << (z + 1)) >> 9) | ((126 - z) << 23);
138 return -fastLog01(pun.f);
145inline float fastExp(
float x)
147 constexpr float a = (1 << 23) / 0.69314718f;
148 constexpr float b = (1 << 23) * (127 - 0.043677448f);
152 constexpr float c = (1 << 23);
153 constexpr float d = (1 << 23) * 255;
155 x = (x < c) ? 0.0f : d;
157 union {
float f; uint32_t u; } pun;
158 pun.u =
static_cast<uint32_t
>(x);