小编Tar*_*ron的帖子

快速将整数乘以适当的分数而没有浮点或溢出的方法

我的程序经常需要执行以下计算:

鉴于:

  • N是32位整数
  • D是32位整数
  • abs(N)<= abs(D)
  • D!= 0
  • X是任意值的32位整数

找:

  • X * N / D为四舍五入的整数,X缩放为N / D(即10 * 2/3 = 7)

显然我可以直接使用r=x*n/d,但经常会从中溢出x*n。如果我改为这样做,r=x*(n/d)则由于整数除法会除去小数部分,因此我只会得到0或x。然后有,r=x*(float(n)/d)但在这种情况下我不能使用浮点数。

精度会很高,但并不像速度和决定性功能那么关键(总是在给定相同输入的情况下返回相同的值)。

N和D当前已签名,但如果有帮助,我可以解决它们始终未签名的问题。

可以使用任何X值(以及N和D,只要N <= D)的泛型函数是理想的,因为此操作以各种不同的方式使用,但是我也有一个特殊的情况,其中X的值是已知的保持2的幂(准确地说是2048),并且加快特定的调用速度将是一个很大的帮助。

目前,我正在使用64位乘法和除法来完成此操作,以避免溢出(本质上是,int multByProperFraction(int x, int n, int d) { return (__int64)x * n / d; }但是有一些断言和多余的位数摆弄而不是舍入)。

不幸的是,我的探查器报告64位除法函数占用了过多的CPU(这是一个32位应用程序)。我尝试减少执行此计算的频率,但用尽了很多方法,因此,即使有可能,我也在尝试找出一种更快的方法。在X的常数为2048的特定情况下,我使用了移位而不是乘法,但这并没有太大帮助。

c++ math bit-manipulation integer-overflow integer-division

13
推荐指数
1
解决办法
295
查看次数