2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Math/Floating.cpp $
15 * Low-level floating point math routines
18 * Revision 1.5 2002/06/09 04:41:22 relnev
19 * added copyright header
21 * Revision 1.4 2002/06/05 08:05:29 relnev
22 * stub/warning removal.
24 * reworked the sound code.
26 * Revision 1.3 2002/05/31 00:29:32 theoddone33
29 * Revision 1.2 2002/05/07 03:16:46 theoddone33
30 * The Great Newline Fix
32 * Revision 1.1.1.1 2002/05/03 03:28:09 root
36 * 2 10/07/98 10:53a Dave
39 * 1 10/07/98 10:49a Dave
41 * 13 2/26/98 3:28p John
42 * Changed all sqrt's to use fl_sqrt. Took out isqrt function
44 * 12 1/30/98 12:25p Mike
45 * Make frand() not return 1.0, which can cause overflow when indexing
48 * 11 1/26/98 10:43p Mike
49 * Make ships not all zoom away from an impending shockwave at the same
50 * time. Based on ai class and randomness
52 * 10 1/20/98 9:47a Mike
53 * Suppress optimized compiler warnings.
54 * Some secondary weapon work.
56 * 9 1/17/98 3:32p Mike
57 * Add rand_range(), returns random float in min..max.
59 * 8 9/09/97 11:07a Sandeep
60 * fixed warning level 4
62 * 7 8/05/97 10:18a Lawrance
63 * my_rand() being used temporarily instead of rand()
65 * 6 2/17/97 5:18p John
66 * Added a bunch of RCS headers to a bunch of old files that don't have
84 #define LOOKUP_POS (EXP_POS-LOOKUP_BITS)
85 #define SEED_POS (EXP_POS-8)
86 #define TABLE_SIZE (2<<LOOKUP_BITS)
87 #define LOOKUP_MASK (TABLE_SIZE-1)
88 #define GET_EXP(a) (((a) >> EXP_POS) & 0xFF )
89 #define SET_EXP(a) ((a) << EXP_POS )
90 #define GET_EMANT(a) (((a) >> LOOKUP_POS) & LOOKUP_MASK )
91 #define SET_MANTSEED(a) (((unsigned long)(a)) << SEED_POS )
93 int fl_magic = 0x59C00000; //representation of 2^51 + 2^52
94 const float *p_fl_magic = (const float *)&fl_magic;
102 static unsigned char iSqrt[TABLE_SIZE];
103 static int iSqrt_inited = 0;
105 static void MakeInverseSqrtLookupTable()
112 for ( f=0, h=iSqrt; f < TABLE_SIZE; f++ ) {
113 fi.i = ((EXP_BIAS-1)<<EXP_POS) | (f<<LOOKUP_POS);
114 fo.f = 1.0f / fl_sqrt(fi.f);
115 *h++ = (unsigned char)(((fo.i + (1<<(SEED_POS-2))) >>SEED_POS ) & 0xFF);
117 iSqrt[ TABLE_SIZE / 2 ] = 0xFF;
122 float fl_isqrt_c( float x )
124 // unsigned long a = ((union _flint *)(&x))->i;
126 // union _flint seed;
130 t1 = timer_get_microseconds();
131 float r1 = 1.0f / (float)sqrt((double)x);
132 t2 = timer_get_microseconds();
133 // float r2 = fl_isqrt_asm(x);
134 t3 = timer_get_microseconds();
139 /* if ( !iSqrt_inited )
140 MakeInverseSqrtLookupTable();
142 seed.i = SET_EXP(((3*EXP_BIAS-1) - GET_EXP(a)) >> 1 ) | SET_MANTSEED(iSqrt[GET_EMANT(a)]);
144 r = (3.0f - r * r * arg ) * r * 0.5f;
145 r = (3.0f - r * r * arg ) * r * 0.5f;
150 // rounds off a floating point number to a multiple of some number
151 float fl_roundoff(float x, int multiple)
153 float half = (float) multiple / 2.0f;
159 return (float) (((int) x / multiple) * multiple);
163 // Return random value in range 0.0..1.0- (1.0- means the closest number less than 1.0)
167 rval = fabsf(((float) myrand()) / (RAND_MAX + 1));
171 // Return a floating point number in the range min..max.
172 float frand_range(float min, float max)
177 rval = rval * (max - min) + min;
182 // Call this in the frame interval to get TRUE chance times per second.
183 // If you want it to return TRUE 3 times per second, call it in the frame interval like so:
184 // rand_chance(flFrametime, 3.0f);
185 int rand_chance(float frametime, float chance) // default value for chance = 1.0f.
187 while (--chance > 0.0f)
188 if (frand() < frametime)
191 return frand() < (frametime * (chance + 1.0f));
194 /*fix fl2f( float x )
197 nf = x*65536.0f + 8390656.0f;
198 return ((*((int *)&nf)) & 0x7FFFFF)-2048;
205 >#define MAGIC (((S * S * 16) + (S*.5)) * S)
207 >#pragma inline float2int;
209 >ulong float2int( float d )
211 > double dtemp = MAGIC + d;
212 > return (*(ulong *)&dtemp) - 0x80000000;