0

C programming I want to generate a float number (money ex 32.52) from a range of 10 to 40, inclusive.

float money;
srand(time(NULL));
money = 10+ ( rand() % (40 - 10 + 1 ));
printf("Show amount: %.2f ",money);

This only generates whole numbers (ex: 17.00 ; 20.00.....)

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Try looking here: http://stackoverflow.com/questions/13408990/how-to-generate-random-float-number-in-c – AntonH Apr 02 '15 at 07:11
  • 3
    What about generating a random number between 100 and 400 and dividing it by 10.0f? You also can adjust the limit values to get every precision you want. – cadaniluk Apr 02 '15 at 07:13
  • 3
    As a small aside, if you're generating production software, you should definitely not use a 'float' to store your monetary values, as the precision of a float is too small. There's already a discussion on it here: http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency That being said, if it's just a formative question, feel free to disregard. The other answers are all valid in showing you how to get a float out of your integer calculation – Matt Taylor Apr 02 '15 at 07:45

3 Answers3

0

Try this:

money = 10 + (float)rand()/RAND_MAX * (40 - 10);
haccks
  • 104,019
  • 25
  • 176
  • 264
  • This formula cannot generate `40.0` exactly. Thus the range `10` to `40` is not inclusive. – chqrlie Apr 02 '15 at 07:50
  • RAND_MAX is the maximum value returned from rand(). 10 + RAND_MAX/RAND_MAX * (40 - 10) = 40 – Brice M. Dempsey Apr 02 '15 at 07:54
  • Right, I mean it can generate 40.0 exactly. – Brice M. Dempsey Apr 02 '15 at 08:10
  • @JamesT.Huggett; No. It can't. – haccks Apr 02 '15 at 08:14
  • My bad, yes it can generate `40.0` exactly... but all the other shortcomings related to the use of `double` or worse `floats` remain. – chqrlie Apr 02 '15 at 09:04
  • @JamesT.Huggett; Read some tutorials about floating point comparison. Do you think `(float)rand()/RAND_MAX ` will ever produce `1.0`? – haccks Apr 02 '15 at 09:31
  • 2
    Actually, there might be cases where this formula will not generate `40.0` exactly: `RAND_MAX` may have a value that cannot be represented exactly as a `float`. For example `INT32_MAX` cannot be converted exactly as a 32 bit `float`. `(float)RAND_MAX/RAND_MAX` will be `1.0` if it is evaluated as `(float)RAND_MAX/(float)RAND_MAX`, but might not if it is evaluated as `(float)RAND_MAX/(double)RAND_MAX`. – chqrlie Apr 02 '15 at 09:34
  • The C11 Standard sates in section 6.3.1.8 that: *Otherwise, if the corresponding real type of either operand is `float`, the other operand is converted, without change of type domain, to a type whose corresponding real type is `float`.* It should be safe to assume that `(float)RAND_MAX/RAND_MAX` must be evaluated as `(float)RAND_MAX/(float)RAND_MAX` but for some reason, I feel uncomfortable relying on this. – chqrlie Apr 02 '15 at 10:17
  • @haccks: never say never! `(float)rand()/RAND_MAX` may rarely produce `1.0` exactly, especially if `RAND_MAX` is large, but what makes you think it should never do it? – chqrlie Apr 02 '15 at 10:23
  • Look at this link http://ideone.com/JlNAl1 It does produce 1.0. I don't know what you guys are going on about. – Brice M. Dempsey Apr 02 '15 at 10:27
  • When rand() returns RAND_MAX then rand()/RAND_MAX == 1. Even if those numbers are rounded in some way. There is nothing else it could equal. – Brice M. Dempsey Apr 02 '15 at 10:30
0

The rand() function generates pseudo-random integers with values between 0 and RAND_MAX inclusive. Your formula involves integer operations thus produces integer values. Your goal can be achieved this way:

double money;

money = 10.0 + (double)rand() * 30.0 / (double)RAND_MAX;
printf("Show amount: %.2f ", money);

This will generate peudo-random floating point values in the target range. It may not fit your purpose because these values will not a be a round number of cents. Indeed IEEE floats or doubles cannot precisely represent all exact numbers of cents. You will come closer by using this method:

money = 10.0 + (double)(rand() % 3001) / 100.0;

values will be as close as possible to exact numbers of cents, but a more accurate and simpler method is just to compute with integer amounts of cents and convert to currency only at print time:

int money = 1000 + rand() % (4000 - 1000 + 1);

printf("Show amount: %d.02d", money / 100, money % 100);

If money can be negative, extra care must be taken to print negative values:

if (money < 0) {
    printf("Show amount: -%u.02u", -money / 100, -money % 100);
} else {
    printf("Show amount: %d.02d", money / 100, money % 100);
}

If you decide to use floating point values, use the double type. Some casts in the above examples are not strictly necessary as promotion rules will make them implicit, I wrote them on purpose for clarity.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
0

Between [10.00 ... 40.00] there are (40.00-10.00)*100 + 1 0.01 numbers.

srand(time(NULL));
#define NUM_COUNT (4000-1000 + 1)
float money = 10.0 + (rand()%NUM_COUNT)/100.0;
printf("Show amount: %.2f ",money);

Recommend using double vs. float. @Matt Taylor

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256