-2

好吧……让我改一下这个问题……

如何在不使用除法或强制转换为双倍的情况下获得整数的 16 分之一......

4

5 回答 5

5
int res = (ref * frac) >> 4

(但有点担心溢出。ref 和 frac 能有多大?如果它可能溢出,先转换为更长的整数类型)

于 2010-12-31T17:24:34.290 回答
2

在任何此类操作中,先乘后除是有意义的。现在,如果您的操作数是整数并且您使用的是可编译语言(例如 C),请使用 shr 4 而不是 /16 - 这将节省一些处理器周期。

于 2010-12-31T17:25:59.873 回答
0

假设这里的所有内容都是整数,任何值得优化的编译器都会注意到 16 是 2 的幂,并相应地移动 frac——只要打开了优化。更担心编译器无法为您做的主要优化。

如果有的话,您应该用括号括ref * frac起来,然后进行除法,因为任何小于 16 的 frac 值都会导致 0,无论是移位还是除法。

于 2010-12-31T17:25:01.617 回答
0

您可以使用左移或右移:

public static final long divisionUsingMultiplication(int a, int b) {
    int temp = b;
    int counter = 0;
    while (temp <= a) {
        temp = temp<<1;
        counter++;
    }
    a -= b<<(counter-1);
    long result = (long)Math.pow(2, counter-1);
    if (b <= a) result += divisionUsingMultiplication(a,b);
    return result;
}

public static final long divisionUsingShift(int a, int b) {
    int absA = Math.abs(a);
    int absB = Math.abs(b);
    int x, y, counter;

    long result = 0L;
    while (absA >= absB) {
        x = absA >> 1;
        y = absB;
        counter = 1;
        while (x >= y) {
            y <<= 1;
            counter <<= 1;
        }
        absA -= y;
        result += counter;
    }
    return (a>0&&b>0 || a<0&&b<0)?result:-result;
}
于 2011-12-29T12:45:48.700 回答
-1

我不明白这个约束,但这个伪代码四舍五入(?):

res = 0
ref= 10
frac = 2
denominator = 16
temp = frac * ref
while temp > 0
   temp -= denominator
   res += 1
repeat
echo res
于 2010-12-31T18:19:14.023 回答