Pxnditx YR
Pxnditx YR

Reputation: 79

I need to get a random number in the range from a to b with n decimal places

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

Answers (3)

Stefano
Stefano

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

eerorika
eerorika

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

WJS
WJS

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

Related Questions