停止小数点前的双除法(精度低,除法快;只得到 'quotient')

Stop double division before decimals (low precision, fast division; getting only the 'quotient')

基本上是一个与性能相关的问题:

我只想从双除法中得到整数商,例如,对于除法 88.3/12.7 = 6.9527559055118110236220472440945,我只想得到 '6' 作为结果。 一个可能的实现当然是:floor(x/y),但是在这里,首先完成了性能密集型双除法,然后 floor 丢弃了双除法所做的大部分 'work'。

所以基本上我想要一个带双精度的除法,它 'stops' 在计算所有这些小数点之前只给我除法的正确整数结果,而不舍入或截断初始双精度参数。有谁知道这个的优雅实现(我搜索了这个主题但没有找到多少)?

我能想到的另一种实现方式是: int(x*1000)/int(y*1000) 可以使用所需的 'precision' 而不是 1000。一个非常简单的实现也是简单地从 x 中减去 y,直到结果小于零。但是,是的,我想知道最好的方法是什么。

此外,简单地 int(x)/int(y) 是不行的,因为它很容易导致错误的结果。

顺便说一下,我知道这可能又是这些 'micro-optimization' 问题之一,这些问题处理的问题在新机器上并不重要,但是,我对这个问题还是有点好奇! :-)

无法提前停止,使用整数除法可能会更慢。

例如,在 Skylake 上:

idiv r/m32 L: 26-27 T: 6
divsd xmm, xmm L: 13-14 T: 4

(source)

所以双除法的速度是原来的两倍,吞吐量也明显更好。那是 before 你考虑额外的乘法和额外的转换。

在较旧的 µarchs 上,32 位整数除法列出的延迟数字通常比双除法低,但是它们变化更大(除法过去更串行),(对于浮点数) 舍入除数更​​快,但对于整数除法,小结果更快。这种特性上的差异可以使它左右摇摆,具体取决于你除以什么。

如您所见,在这种情况下,在没有考虑特定目标的情况下进行优化是危险的,但我想较新的机器比旧机器更有可能成为目标,这意味着双除法或多或少是你能做到的最好的无论如何做(除非其他优化适用)。除单精度浮点数本身速度更快,但会产生转换成本,如果将它们相加,它实际上最终会损失 (5+10)。