0

How do I generate a list of random real numbers between a specific range, ex. -50 to 50? The function I wrote returns a list of only doubles. What I want it to return is something like this: 35, -3, 1.6, 4.5, -22.8, 10, -12, 5.2, 3.6, -8. Here's what I've tried so far...any help is appreciated!

public static double [] randomArray(int A)
{
    double [] randomArr = new double[A];
    Random r = new Random();
    for(int i = 0; i < A; i++)
        {
            randomArr[i] = (r.nextDouble() *(100)) - 50;
        }
    return randomArr;
}
  • 1
    I am afraid that I don’t understand the difference between what you asked for and what you got? Did you want numbers with only 1 decimal? Did you want real real numbers rather than numbers of type `double`? – Ole V.V. Apr 14 '19 at 02:26
  • 2
    *real numbers* is a bad term to use here due to its mathematical definition. It seems that you want a mixture of `int` and `double` where the `double` values are only precise to the first decimal place. Is that correct? – Jacob G. Apr 14 '19 at 02:30
  • @JacobG sorry, my bad. But yes, that's what I meant to say. – user11082882 Apr 14 '19 at 04:48
  • Thanks, @user11082882, for clarifying. Please always do so *in the question itself*. Use the edit link. Your chances of good answers are considerably greater when readers only need to read the question and not the comments. – Ole V.V. Apr 14 '19 at 05:27

3 Answers3

2

Randomly switch between randomly generating a whole or fractional number

You seem to be asking for a random mix of whole numbers (integers, int or Integer) and fractional numbers (float or double, Float or Double). I assume you understand that a random Float/Double could turn out to be a whole number with a fraction of zero, but want to dramatically increase the presence of whole numbers.

There may be more clever ways, but I would use a random number to choose between generating the next number as an integer or as a fractional.

As a random number generator, I suggest ThreadLocalRandom as it is thread-safe by design.

If you want to constrain the range of possible values, specify the optional origin and bound. I cannot imagine why, but it appears that there is no option to specify origin/bound when generating floats, so you must use doubles.

If you want to truncate the fraction to a specific number of digits, see How can I truncate a double to only two decimal places in Java?.

Example code.

int initialCapacity = 10;
List < Number > numbers = new ArrayList <>( initialCapacity );

for ( int i = 1 ; i <= initialCapacity ; i++ )
{
    int which = ThreadLocalRandom.current().nextInt( 2 ); // Produce either 0 or 1. The bound is exclusive, so we specify `2`.
    switch ( which )
    {
        case 0:
            numbers.add( ThreadLocalRandom.current().nextInt( - 50 , 50 ) );
            break;
        case 1:
            numbers.add( ThreadLocalRandom.current().nextDouble( - 50 , 50 ) );
            break;
        default:
            throw new IllegalStateException( "The `which` switch should be only zero or one. Message # 108d8e3f-bce7-4f0f-8dff-652940a17ba1." );
    }
}

When run:

numbers.toString(): [28.344775355282835, -36.00411659190424, 4.151429648004303, -26.898964417043725, 31, 4, 17.172537217625035, 4, 29.957510122739222, -46]

My code assumes you want approximately half and half whole and fractional numbers. If you want a different ratio, play with the range of which and change the switch to a cascading if statement that tests for ranges of numbers. For example, if you want 20% whole numbers, generate 1-10 and result of 1 & 2 produce an Integer while 3-10 produce a Float. Again, there may be more clever approaches mathematically, but this approach gets the job done.

BigDecimal

The float/double & Float/Double types use floating-point technology. Floating-point trades away accuracy for speed of execution. So some numbers cannot be represented to exactly 2 decimal places, for example.

If you care about accuracy more than speed (such as when handling money), substitute BigDecimal where my code used Double.

Auto-boxing

My code above generates a double primitive value, while the List stores objects. Java automatically wraps the primitive as a Double object before storing in the array. If you are unfamiliar with this trick, learn about auto-boxing. See Oracle Tutorial.

Basil Bourque
  • 218,480
  • 72
  • 657
  • 915
0

You can use DecimalFormat.

Snipplet:

import java.util.Random;
import java.text.*;
class Main {
  public static void main(String[] args) {
    System.out.println("Number Format Sample!");
    int n = 5;
    double [] randomArr = randomArray(n);
    DecimalFormat format = new DecimalFormat("0.#");

      for(int i = 0; i < n; i++)
      {
            System.out.println("randomArr item : "+format.format(randomArr[i]));
      }
  }
  public static double [] randomArray(int A)
  {
    double [] randomArr = new double[A];
    Random r = new Random();
    for(int i = 0; i < A; i++)
        {
            randomArr[i] =(r.nextDouble() *(100)) - 50;
        }
    return randomArr;
}
}

Output:

Number Format Sample!
randomArr item : -30.8
randomArr item : -36.9
randomArr item : 44.2
randomArr item : 13.6
randomArr item : -49.1

Ref:https://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html

Hardian
  • 1,594
  • 14
  • 20
  • 1
    Another way of saying this is that there is no *good* way of storing a limited precision number. Instead you store full floats or doubles and then round them when you display them for output. – markspace Apr 14 '19 at 02:37
0

Generates values between -50.0..50.0 inclusive with one decimal point of precision (eg. 42.5). Note: Not all decimal values can be contained perfectly as a floating point value.

for (int i = 0; i < A; i++)
{
    double value = (r.nextInt(501) / 10.0) * (r.nextBoolean() ? 1 : -1);
    randomArr[i] = value;
}
selbie
  • 82,148
  • 13
  • 83
  • 154