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