5
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.

地板和天花板函数包括分别小于/大于或等于 d的最大/最小整数。我想找出分别小于/大于但不等于 d的最大/最小整数。

当然,这可以通过一些if's and but's方法来实现,但我正在寻找一种不包括分支或至少非常快的方法,因为此操作将在算法中执行数十亿次。

二进制操作可能吗?如果没有,最好的选择是什么?

显而易见的解决方案是:

int lessThan = (d - floored) > double.Epsilon ? floored : (floored-1);
int moreThan = (ceiled - d) > double.Epsilon ? ceiled : (ceiled+1);

注意:目的是找出是否d更接近lessThanmoreThan

4

5 回答 5

3

由于d始终为正,您可以使用该转换为整数截断(即,它是正输入的下限和负输入的上限)。

floor(d + 1)相同ceil(d) + 1 if integer, ceil(d) otherwiseceil(d - 1)相同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)

lessThan有点令人费解,如果其他人有更好的想法,我不会感到惊讶。

但既然你想要这个:

目的是找出 d 是否更接近 lessThan 或 moreThan

它应该更简单:

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
于 2012-08-12T15:22:29.693 回答
0

我可能会误解问题,但要找到最接近的 d 整数值:

int floored = (int)d;
int ceiled = (int)(d + 1);
int mathRounded = (int)(d + 0.5)
于 2012-08-12T15:15:53.773 回答
0

不知道你最后想要达到什么结果。

如果你想要ceilfloor最近的是什么:

int lessThan = (int) Math.Floor(d); // Less than or equal to.
int moreThan = (int) Math.Ceiling(d); // Greater than or equal to.

// 1 comparison instead of 2 that is made on your question.
if (lessThan == moreThan)
{
    lessThan--;
    moreThan++;
 }

 bool isCloserToFloor = (d - .5) < lessThan;
 bool isCloserToCeil = !isCloserToFloor;
于 2012-08-12T15:22:12.010 回答
0

尚未对此进行性能测试,但您可以测试您的双精度是否已经是整数,然后执行适当的操作:

double d = 0;
int lessThan;
int moreThan;

if (d % 1 == 0)
{
    lessThan = d - 1;
    moreThan = d + 1;
}
else
{
    lessThan = (int) Math.Floor(d);
    moreThan  = (int) Math.Ceiling(d);
}
于 2012-08-12T15:27:21.790 回答
0

您可以作弊:使用 Convert.ToInt32(bool):

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 = floored - Convert.ToInt32(Math.Abs(d-floored) < epsilon);
int moreThan = ceiled + Convert.ToInt32(Math.Abs(d-ceiled) < epsilon);
于 2012-08-12T15:35:50.410 回答