C# 正系统的快速地板和天花板选择。双值

C# 正系统的快速地板和天花板选择。双值,c#,.net,double,floor,ceil,C#,.net,Double,Floor,Ceil,地板和天花板功能包括分别小于/大于或等于d的最大/最小整数。我想找出分别小于/大于但不等于d的最大/最小整数 当然,这可以通过几个if's和but's来实现,但我正在寻找一种方法,它要么不包括分支,要么至少是非常快的,因为这种操作在一个算法中会执行数十亿次 二进制操作可能吗?如果没有,最好的选择是什么 显而易见的解决方案是: double d = 0; // random decimal value with it's integral part within the range of Int3

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

当然,这可以通过几个
if's和but's
来实现,但我正在寻找一种方法,它要么不包括分支,要么至少是非常快的,因为这种操作在一个算法中会执行数十亿次

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

显而易见的解决方案是:

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
是否更接近
lessThan
大于

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

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

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

如果您想要天花板地板最近的是什么:

int floored = (int)d;
int ceiled = (int)(d + 1);
int mathRounded = (int)(d + 0.5)
int-lessThan=(int)数学地板(d);//小于或等于。
整数大于=(整数)数学上限(d);//大于或等于。
//对你的问题进行1次比较,而不是2次比较。
如果(小于等于大于)
{
lessThan--;
超过++;
}
bool isCloserToFloor=(d-.5)
由于
d
始终为正,您可以使用该转换来截断整数(即正输入为下限,负输入为上限)

floor(d+1)
ceil(d)+1相同,如果是整数,则与ceil(d)相同
ceil(d-1)
floor(d)-1相同,如果是整数,则与floor(d)相同

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;
lessThan
有些复杂,如果有人有更好的想法,我也不会感到惊讶

但既然你想要这个:

目的是找出d是更接近于lessThan还是更接近于lessThan

它应该更简单:

int moreThan = (int)(d + 1); // floor(d + 1)
int lessThan = int.MaxValue + (int)((d - int.MaxValue) - 1) // ceil(d - 1)
double x=d%1;
如果(x==0 | | x==0.5)
//d与其中任何一个的距离相等,相差1或0.5
否则如果(x<0.5)
//d更接近lessThan
其他的
//d更接近于

尚未对此进行测试,但您可以测试double是否已经是整数,然后执行相应的操作:

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

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

double d=0;//整数部分在Int32范围内且始终为正的随机十进制值。
整数地板=(整数)数学地板(d);//小于或等于。
int天花板=(int)数学天花板(d);//大于或等于。
int-lessThan=地板-转换为32(数学Abs(d-地板)
您是否尝试使用少数几个ifs来实现它,并且实际测量到它对您来说太慢了?它已经按照上面的方式实现了。我正试图通过各种方式对算法进行优化来加快算法的速度。这难道不意味着你真的想知道
d%1
是否大于或小于一半或0(特例)?@harold:对于普通地板和天花板来说,这就行了,但对于
小于
大于
的情况就行了,不是吗,只有当
d%1
正好为零时(即
d
是一个整数),才会出现这些差异,对吗?您的if分支永远不会被命中。为什么不呢?如果地板和天花板等于
d
,则Math.Floor和Math.天花将返回相同的整数。测试一下,然后告诉我。嗯。。。我不太明白,只有当
d
本身是一个整数时(这里不是这种情况),地板和天花板才会是相同的。那么,地板和天花板返回等于
d
的值的唯一方法是如果
d
本身是一个整数(在十进制结构上)。如果您确定
d
永远不会是整数值,则无需进行任何检查,只需使用
Math.Floor
天花
即可始终获得小于或大于的正确值。如果
(d-((int)d)
小于
double.Epsilon
,那么
d%1==0
也是正确的吗?我相信d的正值也是正确的。谢谢。你能解释一下最后两行吗。@Raheel Khan:Convert.ToInt32(true)==1;Convert.ToInt32(false)==0;我们只想在Math.Abs(d-floored)时减去1d
转换成负片,这样就可以以另一种方式转换为int。它不必是
int.MaxValue
,只是
d
可以接受的最大值。完美。我只是做了一些比较,加法/减法的开销远远小于目标上的分支。只需确定是否存在任何角点情况顺便说一句,你的想法是Ceil()=>return(int)(d+1);Ceil(d=16)返回17。你应该
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);
}
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);