double d = 0; // random decimal value with it's integral part within the range of Int32 and always positive.
int floored = (int) Math.Floor(d); // Less than or equal to.
int ceiled = (int) Math.Ceiling(d); // Greater than or equal to.
int lessThan = ? // Less than.
int moreThan = ? // Greater than.
The Floor and ceiling functions include the largest/smallest integer that is less than/greater than or equal to d
respectively. I want to find out the largest/smallest integer that is less than/greater than but NOT equal to d
respectively.
OF course this can be achieved through a few if's and but's
but I am looking for a method that either does not include branching or is at least a very fast since this operation will be performed billions of times in an algorithm.
Is binary manipulation possible? If not, what would be the best alternative?
The obvious solution would be something like:
int lessThan = (d - floored) > double.Epsilon ? floored : (floored-1);
int moreThan = (ceiled - d) > double.Epsilon ? ceiled : (ceiled+1);
NOTE: The objective is to find out whether d
is closer to lessThan
or moreThan
.
Since d
is always positive, you can use that casting to an integer truncates (ie it's the floor for positive input and the ceiling for negative input).
floor(d + 1)
is the same as ceil(d) + 1 if integer, ceil(d) otherwise
and ceil(d - 1)
is the same as floor(d) - 1 if integer, floor(d) otherwise
int moreThan = (int)(d + 1); // floor(d + 1)
int lessThan = int.MaxValue + (int)((d - int.MaxValue) - 1) // ceil(d - 1)
The lessThan
is somewhat convoluted, I wouldn't be surprised if someone else has a better idea.
But since you want this:
The objective is to find out whether d is closer to lessThan or moreThan
It should be even simpler:
double x = d % 1;
if (x == 0 || x == 0.5)
// d is equally far from either one, either by a difference of 1 or of 0.5
else if (x < 0.5)
// d is closer to lessThan
else
// d is closer to moreThan