基本上是与绩效相关的问题:
我想从双重除法中得到整数商,例如,对于除法88.3/12.7 = 6.9527559055118110236220472440945
,我只想得到'6'作为结果。
一个可能的实现当然是:floor(x/y)
,但是在这里,首先是完成性能密集的双重划分,然后地板抛弃了双重划分所做的大部分“工作”。
所以基本上我想要一个双重除法,它在计算所有这些小数点之前“停止”并且只给出正确的除法整数结果,而不会舍入或截断初始的双重参数。有谁知道这个优雅的实现(我搜索了这个主题,但没有找到太多)?
我能想象的另一个实现是:
int(x*1000)/int(y*1000)
而不是1000,可以使用所需的“精度”。一个非常简单的实现也可以简单地从x中减去y,直到结果小于零。但是,是的,我想知道最好的方法是什么。
此外,简单地执行int(x)/int(y)
是没有选择的,因为它很容易导致错误的结果。
顺便说一句,我知道这可能是这些“微优化”问题中的一个,这个问题涉及的问题对新机器来说并不重要,但是,我仍然对这个问题有点好奇! : - )
答案 0 :(得分:3)
没有办法提前停止,使用整数除法可能会更慢。
例如,在Skylake:
idiv r/m32 L: 26-27 T: 6
divsd xmm, xmm L: 13-14 T: 4
(source)
因此,双重划分速度提高了两倍,吞吐量明显提高。那是之前你考虑额外的乘法和额外的演员。
在较旧的μarchs上,32位整数除法通常具有比双除法更低的等待时间数,但它们变化更多(除了用于更多串行),(对于浮点数)圆除数更快但对于整数除法,它的结果较小,速度更快。这种特征的差异可以使它以任何方式摆动,这取决于你被什么划分。
正如您所看到的那样,在没有特定目标的情况下进行优化是危险的,但我认为新机器比旧机器更有可能成为目标,这意味着双重划分或多或少是您可以做的最好的(除非适用其他优化)。划分单精度浮点数本身速度更快,但会产生转换成本,如果将它们加起来,实际上最终会丢失(5 + 10)。