Arya
Arya

Reputation: 8985

randomizing decimal portion of a double

I have the following method which takes in GPS coordinates as strings and converts them to doubles with a maximum of 6 decimal points. Now I'm trying to randomize the decimal points starting from the first decimal.

public void randomizeCoordinate(String latString, String lonString)
{
    double lat = Double.parseDouble(latString);
    double lon = Double.parseDouble(lonString);

    DecimalFormat df = new DecimalFormat("#.######");
    df.setRoundingMode(RoundingMode.HALF_EVEN);
    for (Number n : Arrays.asList(lat, lon))
    {
        Double d = n.doubleValue();
        System.out.println(df.format(d));
    }
}

For example if I have 2.34 I want the randomized to be something like 2.493473 or 2.294847 or 2.346758

The first decimal point in which in this case is 3 from 2.34 should only change a maximum of one digit. Up or down randomly. The leading decimal points can change to anything in a random fashion.

What would be the best way of doing this?

Upvotes: 1

Views: 71

Answers (4)

david
david

Reputation: 1016

Use Math.random(), or a subclass of java.util.Random...

 d += 0.1 * (Math.random() * 2 - 1);

That would give you a range from 2.24 to 2.44 for your example.

If you really want a range from 2.20 to 2.39999999..., see @laune's answer.

Upvotes: 0

Some guy
Some guy

Reputation: 1208

The following code will get the min and max ranges for the double that you have entered and generates another random decimal part which is then added to the int part of the original number.

    // Example double
    double lat = Double.parseDouble("2.59");

    // Get the first decimal place
    // http://stackoverflow.com/questions/8164487/getting-the-first-decimal-place-of-a-number
    int first_dec = ( (int)(Math.floor( Math.abs( lat ) * 10 ) ) ) % 10;

    // Get the min and max range
    double min = (double)(first_dec - 1)/10;
    double max = (double)(first_dec + 1)/10;

    // Generate a random number in that range
    Random rand = new Random();
    double randomValue = min + (max - min) * rand.nextDouble();

    // Printing for clarifying
    System.out.println("min = " + min + " : max = " + max + " : randomValue = " + randomValue);

    // Format as required
    DecimalFormat df = new DecimalFormat("#.######");
    System.out.println(df.format((int)lat + randomValue));

For the example double (2.59), this generated the following on multiple runs

min = 0.4 : max = 0.6 : randomValue = 0.5189434537923328
2.518943
min = 0.4 : max = 0.6 : randomValue = 0.5283024116190669
2.528302
min = 0.4 : max = 0.6 : randomValue = 0.44384090285085204
2.443841

Upvotes: 0

laune
laune

Reputation: 31290

Random rand = new Random();
double x = ...;

x = ((int)(x*10) + rand.nextDouble()*2 - 1)/10.0;

Multiply by 10 and truncate to get the digits including the first decimal, add a random number between -1 and 1, scale back.

Note that your doubles will not have just 6 decimal digits; these numbers aren't decimal numbers. For output to show 6 decimals you'll need to format the number by using a format requesting 6 decimal digits.

Upvotes: 1

Tibblez
Tibblez

Reputation: 114

You could find a random number between -100,000 and 100,000, divide it by 1,000,000 then add it to your original number.

It would effectively make your number up to +0.1 or -0.1 different, but in theory could return 0 which would result in the same number.

Upvotes: 0

Related Questions