Peter
Peter

Reputation: 956

javascript float number comparison

I tried to do some sort of "random generator" - there are several adjacent points and depending on their brightness they are more or less likely to be chosen.

a point is an object with x and y coordinates and a bvalue, storing it's brightness.

my approach was to set a p object (p for possibility) which has a start and an end value (both something between 0 and 1) - the difference between the start and the end value depends on their brightness.

I then generate a random number and loop through all points to see, whether the random number is between their start and end property. As one points start value is the previous point's end value only one point should be chosen, but instead a random amount of points are chosen.

Thus I logged the random value and the points' start and end properties. Looks like everything worked, except that the following code

for (i = 0; i < numAdjacentPoints; i++) {
    // set some shorthands
    curr_point = adjacentPoints[i];
    // if there is no previous point, we start with 0
    prev_point = ((i === 0) ? {p: {end: 0}} : adjacentPoints[i-1]);
    // initiate a probability object
    curr_point.p = {};
    // set a start value (the start value is the previous point's end value)
    curr_point.p.start = prev_point.p.end;
    // set an end value (the start value + the point's brightness' share of totalBrightness)
    // -> points with higher darkness (255-b) are more have a higher share -> higher probability to get grown on
    curr_point.p.end   = curr_point.p.start + (255 - curr_point.b) / totalBrightness;
    // if the random value is between the current point's p values, it gets grown on
    if (curr_point.p.start < rand < curr_point.p.end) {
        // add the new point to the path array
        path[path.length] = curr_point;
        // set the point's brightness to white -> it won't come into range any more
        curr_point.b = 255;
        console.log("  we've got a winner! new point is at "+curr_point.x+":"+curr_point.y);
        console.log("  "+curr_point.p.start.toFixed(2)+" < "+rand.toFixed(2)+" < "+curr_point.p.end.toFixed(2));
    }
};

outputs this:

we've got a winner! new point is at 300:132 mycelium.php:269
0.56 < 0.53 < 0.67 mycelium.php:270
we've got a winner! new point is at 301:130 mycelium.php:269
0.67 < 0.53 < 0.78 mycelium.php:270
we've got a winner! new point is at 301:131 mycelium.php:269
0.78 < 0.53 < 0.89 mycelium.php:270
we've got a winner! new point is at 301:132 mycelium.php:269
0.89 < 0.53 < 1.00

--> WTF? 0.56 < 0.53 < 0.67??

Upvotes: 2

Views: 2363

Answers (2)

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382170

You want

if (curr_point.p.start < rand  && rand < curr_point.p.end) {

instead of

if (curr_point.p.start < rand < curr_point.p.end) {

You were comparing a number with the result of a comparison, that is a boolean. Your code was equivalent to

if ((curr_point.p.start < rand) < curr_point.p.end) {

and as a boolean is converted to 1 or 0 when used in such an operation, you were testing

if (0 < 0.67) {

operator precedence in javascript

Upvotes: 5

Binary Brain
Binary Brain

Reputation: 1211

You cannot do this:

if (curr_point.p.start < rand < curr_point.p.end)

Because curr_point.p.start < rand will be evaluated as a boolean and then, you'll have something you don't want: if (boolean < curr_point.p.end)

The correct condition would be something like this:

if (curr_point.p.start < rand  && rand < curr_point.p.end)

In this case you'll have two booleans: if (boolean1 && boolean2) so you can compare them correctly.

Upvotes: 1

Related Questions