19

最も近い整数に丸められた方程式の結果が必要です。例えば

137 * (3/4) = 103

次の間違ったコードを検討してください。

int width1 = 4;
int height1 = 3;

int width2 = 137;
int height2 = width2 * (height1 / width1);

C#で「整数」計算を実行する適切な方法は何ですか?

私は本当にしなければなりませんか:

int height2 = (int)Math.Round(
      (float)width2 * ((float)height1 / (float)width1)
   );
4

12 に答える 12

17

上で述べたように、除算の前に乗算を行う必要があります。とにかく、除数だけをキャストして式を書くことができます。

int height2 = (int)Math.Round(width2 * (height1 / (float)width1));
于 2008-11-18T15:50:29.513 に答える
3

最初に乗算を実行し(オーバーフローする可能性が低い限り)、次に除算を実行します。

整数数学では3/4==0(整数数学は除算では丸められず、切り捨てられます)。

本当に丸めが必要な場合は、固定小数点または浮動小数点で作業するか、モジュラスを試してみる必要があります。

于 2008-11-18T15:45:00.007 に答える
3
int height2 = (width2 * height1) / width1;
于 2008-11-18T15:40:45.570 に答える
2

これはこれを行う最もエレガントな方法だと思います:

Math.round(myinteger * 0.75);

3/4 の代わりに 0.75 を使用すると、暗黙的に double/float にキャストされます。このために提供されているデフォルトの関数を使用しないのはなぜですか?

于 2011-03-15T21:51:53.323 に答える
1

フロートにキャストしないでください。32ビット整数よりも精度が低くなります。浮動小数点を使用する場合は、常にfloatではなくdoubleを使用してください。

于 2009-01-24T19:53:51.203 に答える
1

6 年 (四捨五入) 後、ここに私の貢献があります - 私がずっと前に学んだちょっとしたトリックですが、他の誰もここで言及していないことに驚いています。

アイデアは、除算を行う前に分子に除数の半分を追加して丸めを行うことです。

    int height2 = (width2 * height1 + width1 / 2) / width1;

実際には、OPのように除数が変数である場合には、必ずしもそれを行うことをお勧めしません。代わりに、Math.Round() を使用する方がはるかに理解しやすいため、より良い場合があります。

しかし、除数が定数の場合は、このトリックを使用します。だから代わりに

    int height2 = width2 * height1 / 4;  // No rounding

私は使うだろう

    int height2 = (width2 * height1 + 2) / 4;

より典型的な例を次に示します

  private static Size ResizeWithPercentage(Size oldSize, int resizePercentage)
  {
     return new Size((oldSize.Width * resizePercentage + 50) / 100, 
                     (oldSize.Height * resizePercentage + 50) / 100);
  }

もう 1 つの可能性は、このトリックを dongilmore と supercat によって言及されたアイデアと組み合わせることです。つまり、2 による除算を指定または暗示するのではなく、分子と分母の両方に 2 を掛けることができます。

    int height2 = (width2 * height1 * 2 + width1) / (width1 * 2);

これにより、除数が奇数であるか、奇数である可能性がある場合に、より適切な答えが得られます。

于 2014-07-06T02:54:29.217 に答える
1

ゼロ行のコードを追加して、間違ったコードを修正します。

float width1 = 4;
float height1 = 3;

float width2 = 137;
float height2 = width2 * (height1 / width1);

小数を含む可能性のある変数には浮動小数点数を使用する必要があります。これには、比率から計算された高さが含まれます。問題がある場合は、後でいつでも int にキャストできます。

于 2008-11-19T02:23:15.633 に答える
1

この質問に出くわしました。アーロンの答えは私にはほとんど正しいようです。しかし、問題が「現実世界」の問題である場合は、midpointrounding を指定する必要があると確信しています。したがって、アーロンのコードに基づく私の答えは

int height2 = (int)Math.Round(width2 * (height1 / (float)width1),MidpointRounding.AwayFromZero);

違いを確認するには、コンソールでそのコードを実行します

    Console.WriteLine((int)Math.Round(0.5));
    Console.WriteLine((int)Math.Round(1.5));
    Console.WriteLine((int)Math.Round(2.5));
    Console.WriteLine((int)Math.Round(3.5));
    Console.WriteLine((int)Math.Round(0.5, MidpointRounding.AwayFromZero));
    Console.WriteLine((int)Math.Round(1.5, MidpointRounding.AwayFromZero));
    Console.WriteLine((int)Math.Round(2.5, MidpointRounding.AwayFromZero));
    Console.WriteLine((int)Math.Round(3.5, MidpointRounding.AwayFromZero));
    Console.ReadLine();

詳細については、この記事をご覧ください。

于 2013-09-06T14:11:27.967 に答える
0

ジェフリーのメッセージについて詳しく説明します。通常、32ビット整数をオーバーフローするよりも必要な小数を切り捨てる可能性が高いため(乗算と除算は可換であるため)、除算の前に乗算を行う必要があります。

于 2008-11-18T15:44:52.380 に答える
0

Convert の変換は常に次のように丸められます。

int height2 = Convert.ToInt32(width2 * height1 / (double)width1);
于 2011-08-22T22:40:23.123 に答える
0
int height2 = ((width2 * height1 * 10) + 5) / (width1 * 10);

整数除算の前に、除数がゼロでないことを確認してください。また、これは正の商を想定していることに注意してください。負の場合、丸めは +5 ではなく -5 にする必要があります。

于 2008-11-19T02:09:00.810 に答える