3

I have this random-float function that looks like so:

float randomFloat(float input)
{
    std::mt19937 mt;
    mt.seed(input);
    std::uniform_real_distribution<float> dt(-1,1);

    return dt(mt);
}

as you can see the function takes an input and return an output between -1 and 1

but my problem is that when I give an input float if the number to the left side of the dot is the same. example : (1.2, 1.52, 1.658, 1.01...) the random float will give the same value, (apologize for bad english)

so an input of 1.5 and another input of 1.2 will give the same return value while an input of 1.5 and another input of 2.5 will give different values. how do I fix this ?

keep in mind that I'm not trying to get a randomFloat exactly, my problem is a bit more complicated but if I can get help for this specific problem everything else will be easy to make, and the reason I'm saying this is that I don't want answers telling me to use random_device or that the mt should be seeded once... I already know, this is what I'm working on if you really want to know.

thanks!

Ronald joe
  • 339
  • 2
  • 9

2 Answers2

4

The seed value expected is an unsigned integral type; passing a float is really just passing the truncated integer value of said float.

You can derive this from the signature of seed, which returns result_type, and from the documentation of result_type:

result_type - The integral type generated by the engine. Results are undefined if this is not an unsigned integral type.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • That answers that. You can't really seed with a float. – user4581301 Sep 01 '20 at 17:28
  • so there is no way I can use a float as a seed ? – Ronald joe Sep 01 '20 at 17:30
  • @user4581301: Yep. I suppose if they *needed* the API to accept `float` they could upcast to `double` and multiply by `10000` (or whatever) to make use of some of the value after the decimal point, but it's a poor design even then (you're always going to risk discarding data, either from overflow on the higher end of the magnitude, or from unused precision on the lower end. – ShadowRanger Sep 01 '20 at 17:32
  • @Ronaldjoe: You can convert it to integer preserving more information with [one of these options](https://stackoverflow.com/q/9644327/364696) I guess? It's just not how the API is intended to be used. – ShadowRanger Sep 01 '20 at 17:33
  • 2
    @Ronald "so there is no way I can use a float as a seed ?" - Sure you can - you are already doing that; it just gets truncated. But, you could seed with different parts of your float, like the part before the period as one part of the seed and the remaining bits as a second part or you could break the float into chunks of some number of bits and seed with those. Etc etc. See also https://en.cppreference.com/w/cpp/numeric/random/seed_seq – Jesper Juhl Sep 01 '20 at 17:33
2

std::mt19937 has a result type of std::uint_fast32_t, and this is also the parameter type to seed, so, the float just gets truncated.