0
votes

I'm learning c++ and I'm trying to generate a random float and seem to be having some difficulties.

I start by making a random int(), newRandom, between -100 and 100, then I take that newRandom and turn it into a random float, rand_X, between -1.0 and 1.0. The only caveat is I don't want rand_X to be between -0.2 and 0.2, in other words,

-1.0 <= rand_X <= -0.2 and 0.2 <= rand_X <= 1.0.

Here's my code,

#include "stdafx.h"
#include <iostream>
#include <random>

int newRandom() {
    int newRandom = 0;
    std::random_device rd; // obtain a random number from hardware
    std::mt19937 eng(rd()); // seed the generator
    std::uniform_int_distribution<> distr(-100, 100); // define the range

    newRandom = distr(eng);

    return newRandom;
}

float newRandomX() {
    float rand_X = newRandom() / 100.0f;
    for (int n = 0; n > 0; n++) {
        if (rand_X < 0.0f && rand_X > -0.2f) {
            rand_X = newRandom() / 100.0f;
        }
        else if (rand_X > 0.0f && rand_X < 0.2f) {
            rand_X = newRandom() / 100.0f;
        }
        else {
            return rand_X;
        }
    }
}

int main()
{
    float dir_x = newRandomX();
    std::cout << dir_x;
}

I usually set a break point at the closing bracket of main() and this is my output in the console window, -nan(ind)

As I said I'm learning the language so I'm probably doing something very silly. Thanks very much for your help!

2
What is this for (int n = 0; n > 0; n++) ? - almightyGOSU
Why can't you just use uniform_real_distribution? - awesoon
for (int n = 0; n > 0; n++) { fails the n > 0 condition the first time it's checked, so the loop never runs. Hence, your function executes no return statement, and has undefined behaviour which ostensibly happened to manifest as NaN during your testing. You can use for ( ; ; ) for a loop that runs until return, break, goto, throw, exit etc. are encountered.... - Tony Delroy
Other things you should be aware of: 1) you should not create and seed a new generator every time - make it static. 2) your main function should return a value (0, usually). 3) pay attention to your comparisons, and whether or not something should be > or >=, especially if you invert them like in the answer provided. - paddy
How do you create a static seed? Would I make it a variable that's entered into the newRandow() function? - CaptainGodsey

2 Answers

1
votes

Change your newRandomX() to this:

float newRandomX() {
    float rand_X = newRandom() / 100.0f;
    while(rand_X > -0.2f && rand_X < 0.2f) {
        rand_X = newRandom() / 100.0f;
    }
    return rand_X;
}

Outputs:

0.75
-0.93
-0.43
-0.82
0
votes

Your current code will only generated two decimal digits (note: rounded to nearest value that can be supported by the float format). To get a better distribution (i.e. more digits) you should extend the integer range to be much bigger and then divide by a higher number than 100.0f.

Further there is no need for a while-loop. I would recommend an if-statement instead.

Assume your newRandom generates an integer in range [-80:80] instead of [-100:100] then you could do something like:

float newRandomX() {
    float rand_X = newRandom() / 100.0f;
    if (rand_X < 0) {
        rand_X = rand_x - 0.2;
    } else {
        rand_X = rand_X + 0.2;
    }
    return rand_X;
}

As stated above I would also recommend a bigger integer range.