@@ -130,96 +130,9 @@ PHP_METHOD(Random_Randomizer, nextFloat)
130
130
}
131
131
/* }}} */
132
132
133
- static double getFloat_gamma_low (double x )
134
- {
135
- return x - nextdown (x );
136
- }
137
-
138
- static double getFloat_gamma_high (double x )
139
- {
140
- return nextup (x ) - x ;
141
- }
142
-
143
- static double getFloat_gamma (double x , double y )
144
- {
145
- return (fabs (x ) > fabs (y )) ? getFloat_gamma_high (x ) : getFloat_gamma_low (y );
146
- }
147
-
148
- static uint64_t getFloat_ceilint (double a , double b , double g )
149
- {
150
- double s = b / g - a / g ;
151
- double e ;
152
-
153
- if (fabs (a ) <= fabs (b )) {
154
- e = - a / g - (s - b / g );
155
- } else {
156
- e = b / g - (s + a / g );
157
- }
158
-
159
- double si = ceil (s );
160
-
161
- return (s != si ) ? (uint64_t )si : (uint64_t )si + (e > 0 );
162
- }
163
-
164
- static double getFloat_closed_open (const php_random_algo * algo , php_random_status * status , double min , double max )
165
- {
166
- double g = getFloat_gamma (min , max );
167
- uint64_t hi = getFloat_ceilint (min , max , g );
168
- uint64_t k = algo -> range (status , 1 , hi );
169
-
170
- if (fabs (min ) <= fabs (max )) {
171
- return k == hi ? min : max - k * g ;
172
- } else {
173
- return min + (k - 1 ) * g ;
174
- }
175
- }
176
-
177
- static double getFloat_closed_closed (const php_random_algo * algo , php_random_status * status , double min , double max )
178
- {
179
- double g = getFloat_gamma (min , max );
180
- uint64_t hi = getFloat_ceilint (min , max , g );
181
- uint64_t k = algo -> range (status , 0 , hi );
182
-
183
- if (fabs (min ) <= fabs (max )) {
184
- return k == hi ? min : max - k * g ;
185
- } else {
186
- return k == hi ? max : min + k * g ;
187
- }
188
- }
189
-
190
- static double getFloat_open_closed (const php_random_algo * algo , php_random_status * status , double min , double max )
191
- {
192
- double g = getFloat_gamma (min , max );
193
- uint64_t hi = getFloat_ceilint (min , max , g );
194
- uint64_t k = algo -> range (status , 0 , hi - 1 );
195
-
196
- if (fabs (min ) <= fabs (max )) {
197
- return max - k * g ;
198
- } else {
199
- return k == (hi - 1 ) ? max : min + (k + 1 ) * g ;
200
- }
201
- }
202
-
203
- static double getFloat_open_open (const php_random_algo * algo , php_random_status * status , double min , double max )
204
- {
205
- double g = getFloat_gamma (min , max );
206
- uint64_t hi = getFloat_ceilint (min , max , g );
207
- uint64_t k = algo -> range (status , 1 , hi - 1 );
208
-
209
- if (fabs (min ) <= fabs (max )) {
210
- return max - k * g ;
211
- } else {
212
- return min + k * g ;
213
- }
214
- }
215
-
216
- /* {{{ Generates a random float within [min, max).
217
- *
218
- * The algorithm used is the γ-section algorithm as published in:
133
+ /* {{{ Generates a random float within a configurable interval.
219
134
*
220
- * Drawing Random Floating-Point Numbers from an Interval. Frédéric
221
- * Goualard, ACM Trans. Model. Comput. Simul., 32:3, 2022.
222
- * https://doi.org/10.1145/3503512
135
+ * This method uses the γ-section algorithm by Frédéric Goualard.
223
136
*/
224
137
PHP_METHOD (Random_Randomizer , getFloat )
225
138
{
@@ -251,28 +164,28 @@ PHP_METHOD(Random_Randomizer, getFloat)
251
164
RETURN_THROWS ();
252
165
}
253
166
254
- RETURN_DOUBLE (getFloat_closed_open (randomizer -> algo , randomizer -> status , min , max ));
167
+ RETURN_DOUBLE (php_random_gammasection_closed_open (randomizer -> algo , randomizer -> status , min , max ));
255
168
} else if (zend_string_equals_literal (bounds_name , "ClosedClosed" )) {
256
169
if (UNEXPECTED (max < min )) {
257
170
zend_argument_value_error (2 , "must be greater than or equal to argument #1 ($min)" );
258
171
RETURN_THROWS ();
259
172
}
260
173
261
- RETURN_DOUBLE (getFloat_closed_closed (randomizer -> algo , randomizer -> status , min , max ));
174
+ RETURN_DOUBLE (php_random_gammasection_closed_closed (randomizer -> algo , randomizer -> status , min , max ));
262
175
} else if (zend_string_equals_literal (bounds_name , "OpenClosed" )) {
263
176
if (UNEXPECTED (max <= min )) {
264
177
zend_argument_value_error (2 , "must be greater than argument #1 ($min)" );
265
178
RETURN_THROWS ();
266
179
}
267
180
268
- RETURN_DOUBLE (getFloat_open_closed (randomizer -> algo , randomizer -> status , min , max ));
181
+ RETURN_DOUBLE (php_random_gammasection_open_closed (randomizer -> algo , randomizer -> status , min , max ));
269
182
} else if (zend_string_equals_literal (bounds_name , "OpenOpen" )) {
270
183
if (UNEXPECTED (max <= min )) {
271
184
zend_argument_value_error (2 , "must be greater than argument #1 ($min)" );
272
185
RETURN_THROWS ();
273
186
}
274
187
275
- RETURN_DOUBLE (getFloat_open_open (randomizer -> algo , randomizer -> status , min , max ));
188
+ RETURN_DOUBLE (php_random_gammasection_open_open (randomizer -> algo , randomizer -> status , min , max ));
276
189
} else {
277
190
ZEND_UNREACHABLE ();
278
191
}
0 commit comments