2

I'm having some issues with sorting out a random double to be only one decimal point. I've given it a look online and, from what I can tell and understand, I've got everything correct. Obviously not, however. Specifically, it appears that I may be using 'round()' incorrectly because, even when I don't do all the other multiplication (etc) to it, it doesn't round the double.

double u;
srand(unsigned(time(NULL)));

for(int i = 0; i < 10; i++){
    u = (double)rand()/(RAND_MAX+1) + (rand()%101); //Acquire random number, turn it into decimal and then add it to another number between 0-100.
    u *= 10; //Shift numbers left to remove first decimal from round.
    round(u); //Round to nearest whole number.
    u /= 10; //Shift right to return the first decimal.

    cout<<u<<" "<<flush;
}

This method seems terrible to me. Obviously it won't work up at the higher reaches of double (since *10 might overload it, or whatever it's called). I would like someone to:
A. Show me where I went wrong with this code or, alternatively, hint it.
B. Suggest a better, more efficient way of doing this. As I'm sure there definitely is one.
C. Show me to round to decimal points other than the 1st.

And much appreciated in advance!

Peter O.
  • 32,158
  • 14
  • 82
  • 96
System
  • 23
  • 4
  • 2
    http://stackoverflow.com/questions/11208971/round-a-float-to-a-given-precision – RhinoDevel Mar 04 '16 at 12:41
  • What range of random numbers do you want? – Bathsheba Mar 04 '16 at 12:41
  • Your code doesn't round because you're not doing anything with the rounded value - `round` doesn't modify its parameter, it returns the result. – molbdnilo Mar 04 '16 at 12:56
  • Possible duplicate of [Rounding Number to 2 Decimal Places in C](http://stackoverflow.com/questions/1343890/rounding-number-to-2-decimal-places-in-c) – Ionut Mar 04 '16 at 12:56

2 Answers2

2

I don't know why std::rand() keeps being recommended, when its apparent simplicity is misleading and we have had much better tools for half a decade now.

C++11 random generators are easier to use correctly and you'll get statistically better results. You also have the choice of different engines and distributions, in case you need them.

// Setup
std::default_random_engine generator;
generator.seed(/* truly random seed, e.g. from std::random_device */);
std::uniform_real_distribution<double> distribution(/* your range */);

// Usage
double randomNumber = distribution(generator);
double rounded = std::round(10. * randomNumber) / 10.;
TheOperator
  • 5,936
  • 29
  • 42
  • `double rounded = std::round(10. * rounded) / 10.;`? Typo? – Bathsheba Mar 04 '16 at 12:59
  • @Bathsheba Yes, indeed, thanks. Was that the reason for the downvote? – TheOperator Mar 04 '16 at 13:00
  • I don't know why this was downvoted. Looks good to me, and we all knew what you *meant*. – Bathsheba Mar 04 '16 at 13:01
  • Thanks for this. Just had a look at those links so I'll try to convert any reference of rand() in the tutorials I'm doing to use this method instead. Where is this 'default_random_engine' coming from, however? Is it in automatically available in any c++ program with iostream or is it in a .h file? My test code picked it up immediately. – System Mar 04 '16 at 13:09
  • @System It's in the header ``, as you can see [here](http://en.cppreference.com/w/cpp/numeric/random/random_device) for example. The fact that some standard libraries include more headers than necessary doesn't matter; you should not rely on such behavior because it's not guaranteed. – TheOperator Mar 04 '16 at 13:13
1

You can try to

  1. Generate random integer
  2. Cast it to double
  3. Divide by 10

    double d = rand();
    d /= 10;
    
    // now d will be xxxxx.y
    
LibertyPaul
  • 1,139
  • 8
  • 26