-2

OKAY...この質問を言い換えさせてください...

除算や2倍のキャストを使用せずに、整数の16分の1を取得するにはどうすればよいですか。

4

5 に答える 5

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

(ただし、オーバーフローについては少し心配してください。refとfracはどのくらいの大きさになりますか?オーバーフローする可能性がある場合は、最初に長い整数型にキャストしてください)

于 2010-12-31T17:24:34.290 に答える
2

このような種類の操作では、最初に乗算してから除算するのが理にかなっています。ここで、オペランドが整数で、コンパイル可能な言語(Cなど)を使用している場合は、/16の代わりにshr4を使用します。これにより、プロセッササイクルがいくらか節約されます。

于 2010-12-31T17:25:59.873 に答える
0

ここですべてがintであると仮定すると、そのソルトに値する最適化コンパイラは、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 に答える