1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include "[LCG.h]"20 #include "../../Math/MathFunc.h"21 #include "../../Time/Clock.h"22 #include "../../Math/MathTypes.h"23 #include "../../Math/myassert.h"24 25 [MATH_BEGIN_NAMESPACE]26 27 [LCG::LCG]()28 {29 [Seed]([Clock::TickU32]());30 }31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 void [LCG::Seed](u32 seed, u32 mul, u32 inc, u32 mod)50 {51 [assume]((seed != 0 || inc != 0) && "Initializing LCG with seed=0 && inc=0 results in an infinite series of 0s!");52 #ifndef MATH_SILENT_ASSUME53 if (inc == 0 && (mul % mod == 0 || mod % mul == 0))54 [LOGW]("Warning: Multiplier %u and modulus %u are not compatible since one is a multiple of the other and the increment == 0!", mul, mod);55 #endif56 [assume](mul != 0);57 [assume](mod > 1);58 59 [lastNumber] = seed;60 [multiplier] = mul;61 [increment] = inc;62 [modulus] = mod;63 }64 65 u32 [LCG::IntFast]()66 {67 [assert]([increment] == 0);68 [assert]([multiplier] % 2 == 1 && "Multiplier should be odd for LCG::IntFast(), since modulus==2^32 is even!");69 70 u32 mul = [lastNumber] * [multiplier];71 [lastNumber] = mul + (mul <= [lastNumber]?1:0); 72 [assert]([lastNumber] != 0); 73 return [lastNumber];74 }75 76 u32 [LCG::Int]()77 {78 [assert]([modulus] != 0);79 80 81 82 83 84 85 [u64] newNum = (([u64])[lastNumber] * ([u64])[multiplier] + ([u64])[increment]) % ([u64])[modulus];86 87 88 89 90 91 92 93 94 95 96 97 [assert4]((((u32)newNum) != 0 || increment != 0) && "LCG degenerated to producing a stream of zeroes!", [lastNumber], [multiplier], increment, [modulus]);98 [lastNumber] = (u32)newNum;99 return [lastNumber];100 }101 102 int [LCG::Int](int a, int b)103 {104 [assert](a <= b && "Error in range!");105 106 107 int num = a + (int)([Float]() * (b-a+1));108 109 110 111 if (num < a)112 num = a;113 if (num > b)114 num = b;115 return num;116 }117 118 float [LCG::Float]()119 {120 u32 i = ((u32)[Int]() & 0x007FFFFF ) | 0x3F800000 ;121 float f = [ReinterpretAsFloat](i); 122 f -= 1.f; 123 [assert1](f >= 0.f, f);124 [assert1](f < 1.f, f);125 return f;126 }127 128 float [LCG::Float01Incl]()129 {130 for(int i = 0; i < 100; ++i)131 {132 u32 val = (u32)[Int]() & 0x00FFFFFF;133 if (val > 0x800000)134 continue;135 else if (val == 0x800000)136 return 1.0f;137 else138 {139 val |= 0x3F800000;140 float f = [ReinterpretAsFloat](val) - 1.f;141 [assert1](f >= 0.f, f);142 [assert1](f <= 1.f, f);143 return f;144 }145 }146 return [Float]();147 }148 149 float [LCG::FloatNeg1_1]()150 {151 u32 i = (u32)[Int]();152 u32 [one] = ((i & 0x00800000) << 8) | 0x3F800000 ;153 i = one | (i & 0x007FFFFF) ;154 float f = [ReinterpretAsFloat](i); 155 float fone = [ReinterpretAsFloat](one); 156 f -= fone;157 [assert1](f > -1.f, f);158 [assert1](f < 1.f, f);159 return f;160 }161 162 float [LCG::Float](float a, float b)163 {164 [assume](a <= b && "LCG::Float(a,b): Error in range: b < a!");165 166 if (a == b)167 return a;168 169 for(int i = 0; i < 10; ++i)170 {171 float f = a + [Float]() * (b-a);172 if (f != b)173 {174 [assume2](a <= f, a, b);175 [assume2](f < b || a == b, f, b);176 return f;177 }178 }179 return a;180 }181 182 float [LCG::FloatIncl](float a, float b)183 {184 [assume](a <= b && "LCG::Float(a,b): Error in range: b < a!");185 186 float f = a + [Float]() * (b-a);187 [assume2](a <= f, a, b);188 [assume2](f <= b, f, b);189 return f;190 }191 192 [MATH_END_NAMESPACE] Go back to previous page