4 ms·
I've written an algorithm that generates a uniform random float in the range [a,b] that can produce every representable floating-point value with a probability
by camel-cdr 1y ago
I've written an algorithm that generates a uniform random float in the range [a,b] that can produce every representable floating-point value with a probability proportional to the covered real number range*: https://github.com/camel-cdr/cauldron/blob/main/cauldron/random.h#L1464 https://github.com/camel-cdr/cauldron/blob/main/cauldron/ran...
* Well, almost. I messed up the probability around subnormals slightly and haven't gotten around to fixing it yet.
Still, the algorithm it self should works for all other values and it was measurably more accurate than the regular algorithm.
In terms of performance it is 10x slower compared to the regular implementation of `(randu32(x)>>8)*(1.0f/(1<<24))` on my Zen1 desktop.
- lblume 1y agoHow relevant are subnormals in this context? i.e. what percentage of the range do they occupy and how often would one expect to need to sample to obtain one?
- kbolino 1y agoThere's as many subnormals as there are distinct values with the same exponent, so 2^23 for floats and 2^52 for doubles. This includes the number 0, but you may consider it a special case different from the other subnormals; if so, subtract one. How much of the range they occupy also depends on the interval you're requesting. However, for the common interval from 0 to 1, they occupy about 1/127th of the range for floats and 1/1023rd of the range for doubles. One can reason to this conclusion by noting that the subnormals have the same effective exponent as the smallest normal number (except that they use the 0.xxx representation instead of 1.xxx; the exponent in question is -126 for floats and -1022 for doubles), and then observing that all normal numbers with exponents from that minimum up to and including -1 are also in the range. Since the number 1 is usually not included in the interval, we can ignore it, but even if it was, it would be the only representative from its exponent (0) anyway, so the effect on the size of the range would be miniscule.
- Dylan16807 1y agoYou will never ever ever obtain one. Even calculating your exponent with a single count_trailing_zeros on a single 64 bit value will give you results indistinguishable from perfect.