2010-12-31 11 views
-1

OKAY ... ...私はこの質問を言い換える聞かせ除算除算を使用せずに16による整数またはキャスト

どのように私は分裂を使用するか、または倍増するキャストなしで整数のx 16thsを得ることができます....

+1

を?もしそれが 'int'ならば、fracが2の場合、refは任意の値に対して0になります。 –

+0

@ジョン、テキストではなく、最初のパスであるコードではないと思います。 –

+0

"int res =(ref >> 4)* frac"を試しましたか? – DwB

答えて

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

(ただし、オーバーフローについてAA少し心配。REFと、それは最初の長い整数型にキャスト、オーバーフローすることができればFRACは?取得することができますどのくらいの大きさ)その塩の価値が、ここではint型のすべてをしていると仮定すると、

0

任意の最適化コンパイラを16が2の累乗であることに気づくでしょう。それに応じて、最適化オンになっています。コンパイラがあなたのためにできない主な最適化についてもっと心配してください。

何かがある場合は、ref * fracを括弧でくくってから、fracの値が16未満の場合、シフトまたは除算のいずれかで0になるため、除算を行う必要があります。

+0

OPはC言語などを実装言語として使用していない可能性がありますが、言語固有のタグはありませんでした。 –

+0

言語は重要ではなく、ビットが保持できる値の数だけです。正直なところ、良い動的言語通訳者はプリミティブな数字の型について同じことに気づくはずなので、 "コンパイラまたはインタプリタ"として本当の "コンパイラ"を望むならば、IMO。 –

+0

値が常に数字であることが証明できる場合にのみ、本当に。実行時にチェックする必要がある場合は、チェックのオーバーヘッドがすべての可能な最適化を上回る可能性があります。 –

2

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

-1

私は制約を理解していないが、この擬似コードは切り上げ(?):

res = 0 
ref= 10 
frac = 2 
denominator = 16 
temp = frac * ref 
while temp > 0 
    temp -= denominator 
    res += 1 
repeat 
echo res 
+0

そしておそらくもっとも遅い実装の賞を取るでしょう。 frac = 2、ref = MAXINT/2を考えてみましょう。それはまた、他の解決策のオーバーフローの問題を持っています –

+0

ねえ、私は全部が病気のアドバイスだと思う! :)分裂の制約の現実的な理由はありますか? – horatio

+0

私が作業しているプラ​​ットフォームの分割は、加減算/シフトより約25倍遅く、乗算よりも約10倍遅いです。いくつかのアプリケーションでは、代替パスを見つけようとするためにホット・パスに分割を行うのに十分なコードがあります。 – Chuu

0

あなたは左シフトまたは右シフトを使用することができます:FRACの種類は何

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; 
}