1 #ifndef FAST_POW2
2 #define FAST_POW2
3 
4 // Copied from fastexp.h
5 // See that file for copyright info.
6 
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <stdio.h>
main(int argc,char * argv[])10 
11 #include <cassert>
12 
13 //#ifdef __cplusplus
14 //#define cast_uint32_t static_cast<uint32_t>
15 //#else
16 #define cast_uint32_t (uint32_t)
17 //#endif
18 
19 //#define DEBUG_FASTPOW2
20 
21 #ifdef DEBUG_FASTPOW2
22 static int counter = 0;
23 #endif
24 
25 static inline float
26 fastpow2 (float p)
27 {
28   //static_assert(sizeof(float)==4,"float not 32 bits!");
29   if (p == 0) {
30     return 1.0;
31   }
32   float offset = (p < 0) ? 1.0f : 0.0f;
33   float clipp = (p < -126) ? -126.0f : p;
34   int w = clipp;
35   float z = clipp - w + offset;
36   union { uint32_t i; float f; } v = { cast_uint32_t ( (1 << 23) * (clipp + 121.2740575f + 27.7280233f / (4.84252568f - z) - 1.49012907f * z) ) };
37 
38 #ifdef DEBUG_FASTPOW2
39     if (counter++ >= 1024) {
40         printf("fastpow2: 2 ^ %f = %f ~ %f\n", p, powf(2.0,p), v.f);
41         counter = 0;
42     };
43 #endif
44 
45  return v.f;
46 }
47 
48 // NOT SUFFICIENTLY ACCURATE - USE fastpow2 above.
49 // This one causes very noticeable overdamping of high-frequency notes
50 static inline float
51 fasterpow2 (float p)
52 {
53   //static_assert(sizeof(float)==4,"float not 32 bits!");
54   fprintf(stderr,"*** fasterpow2 is NOT SUFFICIENTLY ACCURATE - use fastpow2 (below) instead\n");
55   exit(1);
56   float clipp = (p < -126) ? -126.0f : p;
57   union { uint32_t i; float f; } v = { cast_uint32_t ( (1 << 23) * (clipp + 126.94269504f) ) };
58 
59 #ifdef DEBUG_FASTPOW2
60     if (counter++ >= 1024) {
61         printf("fasterpow2: 2 ^ %f = %f ~ %f\n", p, powf(2.0,p), v.f);
62         counter = 0;
63     };
64 #endif
65 
66   return v.f;
67 }
68 
69 #endif
70