This is Random.m in view mode; [Download] [Up]
#import "Random.h" #import <appkit/nextstd.h> #import <limits.h> /* External Function Declarations */ #define RAND_NORM ((float) LONG_MAX +1.0) #define UnitRandom ((float)random() / RAND_NORM) extern long random(); extern void srandom(int seed); extern char *initstate(unsigned seed, char *state, int n); extern char *setstate(char *state); #define RANTYPE_FLAT 0 #define RANTYPE_EXP 1 #define RANTYPE_GAUSS 2 static float gaussValue() { static BOOL saved = NO; static float extraG; float fac, r, v1, v2; if (!saved) { do { v1 = 2.0 * UnitRandom - 1.0; v2 = 2.0 * UnitRandom - 1.0; r = v1 * v1 + v2 * v2; } while (r >= 1.0); /* if (r == 0.0) r = 0.000001; */ fac = sqrt( -2.0 * log(r) / r); extraG = v1 * fac; saved = YES; return (v2 * fac); } else { saved = NO; return (extraG); } } @implementation Random /* Creating and freeing a Random object */ + initialize { srandom(time(0)); /* Seed Random Number Generator */ return self; } + new { return [self newCount:16]; } + newCount:(unsigned)numSlots /* Number of bytes of State data */ { static char *old; static char *new; int size; size = (numSlots < 8) ? 8 : numSlots; NX_MALLOC(new,char,size); old = initstate(time(0),new,size); self = [super new]; range = 1.0; return self; } - seed /* Will generate a new sequence */ { srandom(time(0)); return self; } - seedFixed /* Will generate a fixed sequence */ { srandom(1); return self; } - (int)integer { return random(); } - (float) unit { /* Between 0 and 1 */ switch(type) { case RANTYPE_EXP: return -log(UnitRandom); case RANTYPE_GAUSS: return gaussValue(); case RANTYPE_FLAT: default: return UnitRandom; } } - (float)scaleFrom:(float)nLow to:(float)nHigh { low = nLow; range = nHigh - nLow; return [self flat]; } - (float)scaleMean:(float)nMean stdDev:(float)nDev { low = nMean; range = nDev; return [self gauss]; } - (float)number { return low + [self unit] * range; } - (int)whole { return (int)floor([self number]); } - (float)flat { type = RANTYPE_FLAT; return [self number]; } - (float)exp { type = RANTYPE_EXP; return [self number]; } - (float)gauss { type = RANTYPE_GAUSS; return [self number]; } - (int)partition:(int)numTotal part:(int)num of:(int)denom { range = numTotal / (denom ? denom : 1); low = num * range; return [self whole]; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.