Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
以C#为单位的整数除法舍入(对于负数)_C#_Math - Fatal编程技术网

以C#为单位的整数除法舍入(对于负数)

以C#为单位的整数除法舍入(对于负数),c#,math,C#,Math,有没有办法在C#中执行整数除法(没有浮点或十进制,我需要让这一个保持非常快)来舍入数字 默认除法只是丢弃分数参数。考虑: 1 / 2 = 0 // That is correct -1 / 2 = 0 // ... but I want to get (-1) here! 我的除法将以正数和负数表示除法。我不需要使用if,因为分支成本太高(该操作将在实时游戏引擎中频繁运行)如果要将a除以b: 不会因溢出而失败的方法: int res = a / b; return (a < 0 &am

有没有办法在C#中执行整数除法(没有浮点或十进制,我需要让这一个保持非常快)来舍入数字

默认除法只是丢弃分数参数。考虑:

 1 / 2 = 0 // That is correct
-1 / 2 = 0 // ... but I want to get (-1) here!

我的除法将以正数和负数表示除法。我不需要使用
if
,因为分支成本太高(该操作将在实时游戏引擎中频繁运行)

如果要将
a
除以
b

不会因溢出而失败的方法:

int res = a / b;
return (a < 0 && a != b * res) ? res - 1 : res;
更明确的一点是:

return a >= 0 ? a / b : (a - b + 1) / b;

除以2是一个简单的按位右移。在@elgonzo(现已删除)提到C#右移的属性后,我决定看看它是如何工作的,它似乎正是你想要的:

var result = number >> 1;
这将产生以下结果:

11->5
10->5
2->1
1->0
-1->-1
-2->-1
-32->-16
-33->-17

int.MaxValue和MinValue也起作用

就性能而言,这似乎是目前使用模运算符的公认答案的两倍。 在我的机器上,使用简单的移位除以(相同的)100000000个随机数需要2.17秒,而使用带模的版本需要3.1到4.0秒


分支版本的性能似乎与模版本几乎相同:明显比简单的右移慢。

在除以负数之前先从负数中减去1(对于非负数,不要这样做)@elgonzo我不知道这个数是否为负数。它可以是正的也可以是负的当然你可以知道这一点,换句话说,你的代码可以计算出一个数字是否是负的…你认为浮点数慢的原因是什么?您可能正在想象一个不存在的问题。@elgonzo我需要
if
或任何其他形式的分支,这是一种非常昂贵的操作。我只知道存在负溢出的风险。请注意,在考虑CPU分支预测功能时,模运算可能比简单分支的成本更高(由于某些最近CPU漏洞(如Spectre/Meldown)的缓解措施可能会对分支预测性能增益产生影响,无法承受)3个版本使用分支,第四个版本使用2个模运算。我建议对性能进行测试…测试后,看起来所有这些选项都比简单的
n>>1
慢得多,同时做同样的工作。@oerkelens,当然。但是
n>>1
只除以
2
。你必须处理其他整数。该死!看不到森林里所有的树。来,让我投一票。(值得一提的是,我删除了我过于复杂的答案,试图不分散我对答案简单性的注意力。老兄,我可以为此责备周末吗?;-P)@elgonzo好吧,你给了我正确的方向,谢谢你:)
return a >= 0 ? a / b : (a - b + 1) / b;
var result = number >> 1;