Reputation: 79
I need a function that returns me a random number with n decimal places Example:
int aleatorio(int li, int ls)
{
return rand()%(ls+1-li)+li;
}
What i want is:
float new_random(int start, int final, int number_decimals)
{
return // What should I write here?
}
if I would call this function 5 times like this::
new_random(0, 5, 4);
The exit would be:
0.2344
3.4356
2.8435
4.2435
I do not want to use this, because I need numbers of 4 exact decimal places since I will not use them to print, but you will have others:
cout << setprecision(4) << 4.24359675967 << endl; //I do not want this
Upvotes: 0
Views: 486
Reputation: 23
You can generate an integer number N between start and final * 10^number_decimals and then return N / 10^number_decimals
Eg. start = 0, final = 5, number_decimals = 4 ==> N in [0 - 50000] ==> N/10000 in [0.0000 - 5.0000]
float new_random(int start, int final, int number_decimals) {
return aleatorio(start, final*pow10(number_decimals))/number_decimals;
}
You can define pow10 as:
int pow10(int p) {
if (p == 0) return 1;
else return 10 * pow10(p-1);
}
Upvotes: 0
Reputation: 238311
I need numbers of 4 exact decimal places
Then you cannot use finite precision binary floating point (i.e. float
, double
or long double
) because those types cannot exactly represent all of the values with 4 decimal places.
A solution is to use arbitrary precision floating point, and another is to use fixed point. C++ standard doesn't provide arbitrary precision types nor fixed point types. Another approach is to give up the requirement of exactly representing those values and accept the almost exact values that are achievable with limited precision.
Upvotes: 1
Reputation: 40034
Try this for a Java solution. Multiply the start and finish by 1000, generating ints between the range and then divide the resultant number by 1000 as a double.
int start = 20;
int finish = 30;
int count = 10;
Random r = new Random();
r.ints(start * 1000, finish * 1000).filter(n -> n % 10 != 0)
.limit(count).mapToDouble(n -> n / 1000.)
.forEach(System.out::println);
prints something like this.
21.186
26.983
25.345
20.764
27.911
21.139
24.679
27.722
29.443
28.675
Or as a method supplying the starting number, ending number and precision.
for (int i = 0; i < 10; i++) {
System.out.println(newRandom(start,finish,4));
}
static Random r = new Random();
public static Double newRandom(int start, int finish, int precision) {
int f = (int)Math.pow(10,precision);
return r.ints(start * f, finish * f).filter(n -> n % 10 != 0)
.limit(1).mapToDouble(n -> n / (double)f).findFirst().getAsDouble();
}
Prints something like this.
28.4444
25.0259
29.5611
25.6445
25.4977
28.5124
28.9709
23.4835
27.9766
23.9438
Upvotes: 0