2

この擬似コードを理解しようとしています。以下を想定しています。...符号なし整数と符号付き整数(またはlong)のみを使用できます。除算は、余りのない実数を返します。MODは実数を返します。分数と小数は処理されません。

INT I = 41828;
INT C = 15;
INT D = 0;

D = (I / 65535) * C;

この状況で小数(または小数値)をどのように処理しますか?余りを表すために負の値を使用する方法はありますか?

この例では、I / 65535は0.638である必要がありますが、制限があり、MODが638の場合は0になります。次に、Cを掛けて正しい答えを得るにはどうすればよいですか?

それが理にかなっていることを願っています。

ここでのMODは、実際には638ではなく23707を返します。

4

3 に答える 3

3

その最後の行で演算の順序を切り替えると、探している整数の答えが得られます(私の計算が正しければ、9)

D = (I * C) / 65535
/* D == 9 */

それがあなたが探している答えですか?

于 2010-04-02T22:02:28.020 に答える
0

これらがこの計算に常に使用している値であると仮定すると、次のようになります。

D = I /(65535 / C);

また

D = I / 4369;

Cは65535の因数であるため、これは、使用可能な整数の範囲をオーバーランする可能性を減らすのに役立ちます(つまり、16ビットの符号なし整数しかない場合)。

より一般的なケースでは、IとCを乗算すると、使用している整数型の許容範囲外の値になるリスクがあると思われる場合(最終結果がその範囲内であっても)、次のように、分子と分母のGCDを除外できます。

INT I = 41828;
INT C = 15;
INT DEN = 65535;

INT GCDI = GCD(I、DEN);
DEN = DEN / GCDI;
I = I / GCDI;

INT GCDC = GCD(C、DEN);
DEN = DEN / GCDC;
C = C / GCDC;

INT D =(I * C)/ DEN;

ここで、DENは分母(この場合は65535)です。これは、特にIとCが両方ともDENと互いに素であり、I * C> MAX_INTである場合は特に、すべての場合に正しい答えを提供するわけではありません。

あなたが提起するより大きな質問に関しては、整数値の除算は常に小数成分を失います(床関数と同等)。「小数」部分と見なされる部分に含まれる情報を保持する唯一の方法は、モジュラスから導出できる余りを使用することです。これらの異なる数体系の意味を混同しないことを強くお勧めします。整数はまさにその整数です。それらを浮動小数点数にする必要がある場合は、実際にはintではなくfloatを使用する必要があります。興味があるのが小数部分をユーザーに表示することだけである場合(つまり、それをさらに計算するために実際に使用していない場合)、剰余を表す文字列に変換するルーチンを作成できます。

于 2010-04-06T15:35:47.070 に答える
0

さて、小数を処理する1つの方法は、この置換除算関数です。この手法には多くの明らかな欠点があります。

ALT DIV (dividend, divisor) returns (decimal, point)
for point = 0 to 99
  if dividend mod divisor = 0 return dividend / divisor, point
  dividend = divident * 10
return dividend / divisor, 100
于 2010-04-06T15:46:06.243 に答える