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.