# Output distribution of rand(Float32) and rand(Float64), thread 2

**URL:** <https://discourse.julialang.org/t/output-distribution-of-rand-float32-and-rand-float64-thread-2/105184>\
**Category:** Internals & Design\
**Tags:** float, random\
**Created:** [October 19, 2023, 1:10pm UTC](https://discourse.julialang.org/t/output-distribution-of-rand-float32-and-rand-float64-thread-2/105184 "2023-10-19T13:10:07Z")\
**Posts on this page:** 1\
**Showing post:** 58

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [October 24, 2023, 3:05pm UTC](https://discourse.julialang.org/t/output-distribution-of-rand-float32-and-rand-float64-thread-2/105184/58 "2023-10-24T15:05:23Z")

</div>

> [@foobar\_lv2](#):
>
> But I am arguing strenuously that `x + epsilon` with `epsilon` determined by the number of mantissa bits is conceptually wrong for floating point numbers – it misses the point of floating the point, and we must do better.

I’m still missing a wholistic view on the motivation here. I _totally_ get the theoretical attraction to being able to sample from all _representable_ values, but I’m not really understanding the practical objectives and tradeoffs. Even Downey’s paper draft and the python docs are silent on this practical view.

- There’s the not-outputting 0 thing. This part I get — not only does it cause the potential for a rare (or not-so-rare) singularity, its inclusion also ever-so-slightly biases the mean of rand to be less than 0.5. But it’s also trivial to do rejection sampling while being highly impractical to do the inverse. Ultimately, its exclusion was considered and declined, even in the face of — at the time — a near-zero performance cost and improved overall statistics.
- So then there’s increasing the density of the possible sampled points from the real line (prior to rounding). Potential numbers for this density are:
  - 2^{-11}: Float16 status quo
  - 2^{-24}: Float32 status quo (and the dense sampling of all possible Float16 values including subnormals)
  - 2^{-52}: Float64 before Julia v1.7
  - 2^{-53}: Float64 status quo
  - 2^{-76}: The optimized Float64 [algorithm from the blog post on corsix.org](https://www.corsix.org/content/higher-quality-random-floats)
  - 2^{-126}: Dense sampling of all possible normal Float32 values
  - 2^{-149}: Dense sampling of all possible Float32 values, including subnormals
  - 2^{-1022}: Dense sampling of all possible normal Float64 values
  - 2^{-1074}: Dense sampling of all possible Float64 values, including subnormals

Where the line for “good enough” is drawn will obviously depend on what you’re doing with the random numbers. So what are some example lines in the sand? Are there algorithms that would have significant error with 2^{-53} but not with some 2^x?

---

_[View the full topic](https://discourse.julialang.org/t/output-distribution-of-rand-float32-and-rand-float64-thread-2/105184)._
