views:

24

answers:

2

I am representing wind directions using integer values (an Enum) ranging from 0 for North, through to 15 for North-North-West.

I need to check if a given wind direction (integer value between 0 and 15) is within a certain range. I specify my WindDirectionFrom value first moving clockwise to WindDirectionTo to specify the range of allowable wind direction.

Obviously if WindDirectionFrom=0 and WindDirectionTo=4 (between N and E direction) and the wind direction is NE (2) the calculation is simply

int currentWindDirection = 2;
bool inRange = (WindDirectionFrom <= currentWindDirection && currentWindDirection <= WindDirectionTo); 
              //(0 <= 2 && 2 <= 4) simple enough...

However for a different case where say WindDirectionFrom=15, WindDirectionTo=4 and wind direction is NE (2) again, the calculation immediately breaks...

bool inRange = (WindDirectionFrom <= currentWindDirection && currentWindDirection <= WindDirectionTo); 
              //(15 <= 2 && 2 <= 4) oops :(

I'm sure this can't be too difficult, but I'm having a real mental block with this one.

+2  A: 

What you want is modular arithmetic. Do your arithmetic mod 16, and check to see if the difference is from (say) at least 14 (the modular equivalent of -2) or at most 2.

How to do modular arithmetic will vary between languages. With C or C++, you would find x mod 16 as follows:

int xm = x % 16;
if (xm < 0) xm += 16;

(Thanks to msw for pointing out that arithmetic on enums is frequently not allowed, and for good reasons. An enum normally represents objects or conditions that are discrete and not related arithmetically.)

David Thornley
Aah right, well I'm using C# so I guess it's going to be pretty much the same syntax as you've got here.
mdresser
Correct, except many languages won't allow arithmetic on enums (for good reason). The OP will have to get his enums into numerics.
msw
+1  A: 

I would do it like this:

int normedDirection( int direction, int norm )
{
   return (NumberOfDirections + currentDirection - norm) % NumberOfDirections;
}

int normed = normedDirection( currentWindDirection, WindDirectionFrom );
bool inRange = (0 <= normed && normed <= normedDirection( WindDirectionTo, WindDirectionFrom ); 
Peter G.