]> icculus.org git repositories - taylor/freespace2.git/blob - src/math/floating.cpp
Initial revision
[taylor/freespace2.git] / src / math / floating.cpp
1 /*
2  * $Logfile: /Freespace2/code/Math/Floating.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Low-level floating point math routines
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:09  root
11  * Initial revision
12  *
13  * 
14  * 2     10/07/98 10:53a Dave
15  * Initial checkin.
16  * 
17  * 1     10/07/98 10:49a Dave
18  * 
19  * 13    2/26/98 3:28p John
20  * Changed all sqrt's to use fl_sqrt.  Took out isqrt function
21  * 
22  * 12    1/30/98 12:25p Mike
23  * Make frand() not return 1.0, which can cause overflow when indexing
24  * into arrays.
25  * 
26  * 11    1/26/98 10:43p Mike
27  * Make ships not all zoom away from an impending shockwave at the same
28  * time.  Based on ai class and randomness
29  * 
30  * 10    1/20/98 9:47a Mike
31  * Suppress optimized compiler warnings.
32  * Some secondary weapon work.
33  * 
34  * 9     1/17/98 3:32p Mike
35  * Add rand_range(), returns random float in min..max.
36  * 
37  * 8     9/09/97 11:07a Sandeep
38  * fixed warning level 4
39  * 
40  * 7     8/05/97 10:18a Lawrance
41  * my_rand() being used temporarily instead of rand()
42  * 
43  * 6     2/17/97 5:18p John
44  * Added a bunch of RCS headers to a bunch of old files that don't have
45  * them.
46  *
47  * $NoKeywords: $
48  */
49
50 #include <stdlib.h>
51 #include <math.h>
52
53 #include "pstypes.h"
54 #include "floating.h"
55 #include "timer.h"
56
57 #define LOOKUP_BITS     6
58 #define EXP_POS         23
59 #define EXP_BIAS                127
60 typedef float FLOAT;
61
62 #define LOOKUP_POS      (EXP_POS-LOOKUP_BITS)
63 #define SEED_POS                (EXP_POS-8)
64 #define TABLE_SIZE      (2<<LOOKUP_BITS)
65 #define LOOKUP_MASK     (TABLE_SIZE-1)
66 #define GET_EXP(a)      (((a) >> EXP_POS) & 0xFF )
67 #define SET_EXP(a)      ((a) << EXP_POS )
68 #define GET_EMANT(a)    (((a) >> LOOKUP_POS) & LOOKUP_MASK )
69 #define SET_MANTSEED(a) (((unsigned long)(a)) << SEED_POS )
70
71 static unsigned char iSqrt[TABLE_SIZE];
72 static int iSqrt_inited = 0;
73
74 int fl_magic = 0x59C00000;              //representation of 2^51 + 2^52
75 const float *p_fl_magic = (const float *)&fl_magic;
76
77 union _flint {
78         unsigned long   i;
79         float                           f;
80 } fi, fo;
81
82 /*
83 static void MakeInverseSqrtLookupTable()
84 {
85         long f;
86         unsigned char *h;
87         union _flint fi, fo;
88
89         iSqrt_inited = 1;
90         for ( f=0, h=iSqrt; f < TABLE_SIZE; f++ )       {
91                 fi.i = ((EXP_BIAS-1)<<EXP_POS) | (f<<LOOKUP_POS);
92                 fo.f = 1.0f / fl_sqrt(fi.f);
93                 *h++ = (unsigned char)(((fo.i + (1<<(SEED_POS-2))) >>SEED_POS ) & 0xFF);
94         }
95         iSqrt[ TABLE_SIZE / 2 ] = 0xFF;
96 }
97 */
98
99 // HACK!
100 float fl_isqrt_c( float x )
101 {
102 //      unsigned long a = ((union _flint *)(&x))->i;
103 //      float arg = x;
104 //      union _flint seed;
105 //      FLOAT r;
106
107         int t1, t2, t3;
108         t1 = timer_get_microseconds();
109         float r1 =  1.0f / (float)sqrt((double)x);
110         t2 = timer_get_microseconds();
111 //      float r2 = fl_isqrt_asm(x);
112         t3 = timer_get_microseconds();  
113
114         return r1;
115
116
117 /*      if ( !iSqrt_inited )
118                 MakeInverseSqrtLookupTable();
119
120         seed.i = SET_EXP(((3*EXP_BIAS-1) - GET_EXP(a)) >> 1 ) | SET_MANTSEED(iSqrt[GET_EMANT(a)]);
121         r = seed.f;
122         r = (3.0f - r * r * arg ) * r * 0.5f;
123         r = (3.0f - r * r * arg ) * r * 0.5f;
124         return r;
125 */
126 }
127
128 // rounds off a floating point number to a multiple of some number
129 float fl_roundoff(float x, int multiple)
130 {
131         float half = (float) multiple / 2.0f;
132
133         if (x < 0)
134                 half = -half;
135
136         x += half;
137         return (float) (((int) x / multiple) * multiple);
138 }
139
140
141 //      Return random value in range 0.0..1.0- (1.0- means the closest number less than 1.0)
142 float frand()
143 {
144         float rval;
145         rval = ((float) myrand()) / (RAND_MAX + 1);
146         return rval;
147 }
148
149 //      Return a floating point number in the range min..max.
150 float frand_range(float min, float max)
151 {
152         float   rval;
153         
154         rval = frand();
155         rval = rval * (max - min) + min;
156
157         return rval;
158 }
159
160 //      Call this in the frame interval to get TRUE chance times per second.
161 //      If you want it to return TRUE 3 times per second, call it in the frame interval like so:
162 //              rand_chance(flFrametime, 3.0f);
163 int rand_chance(float frametime, float chance)  //      default value for chance = 1.0f.
164 {
165         while (--chance > 0.0f)
166                 if (frand() < frametime)
167                         return 1;
168
169         return frand() < (frametime * (chance + 1.0f));
170 }
171
172 /*fix fl2f( float x )
173 {
174         float nf;
175         nf = x*65536.0f + 8390656.0f;
176         return ((*((int *)&nf)) & 0x7FFFFF)-2048;
177 }
178 */
179
180
181 /*
182 >#define  S  65536.0
183 >#define  MAGIC  (((S * S * 16) + (S*.5)) * S)
184 >
185 >#pragma inline float2int;
186 >
187 >ulong float2int( float d )
188 >{
189 >  double dtemp = MAGIC + d;
190 >  return (*(ulong *)&dtemp) - 0x80000000;
191 >}
192
193 */