7

形を表すクラスがあります。Shapeクラスには、Angleというプロパティがあります。このプロパティのセッターが値を[0,359]の範囲に自動的にラップするようにします。

残念ながら、単純_Angle = value % 360;は正の数に対してのみ機能します。C#では、-40 % 360 == -40。Google calcは、私が望む方法でそれを行います。値は320である必要があります。

C#で最もエレガントなソリューションは何ですか?

これが私がこれまでに得た最良の方法です:

     public double Angle {
        get { return _Angle; } 
        set {
            if ( value >= 0 ) {
                _Angle = value % 360;
            }
            else {
                _Angle = value - (360 * ((int)(value / 360) - 1)); 
            }
        }
    }

編集:

みんなありがとう、私は今持っています:

     public double Angle {
        get { return _Angle; } 
        set {
            _Angle = (value % 360) + ((value < 0) ? 360 : 0);
        }
    }

..どちらがはるかに優れています:)

4

7 に答える 7

10

これは Java の場合ですが、Java もモジュラスに対して同じ動作をします。(つまり-40 % 360 == -40)。

以下のコードは [0. 360)、与えられた角度、正または負に関係なく。

public class Mod
{
    public static int mod(int a, int b)
    {
        if (a < 0)
            return b + (a % b);
        else
            return a % b;
    }

    public static void main(String[] args)
    {
        System.out.println(mod(40, 360));   // 40
        System.out.println(mod(-40, 360));  // 320
        System.out.println(mod(-400, 360)); // 320
    }
}

指定された角度が -360 を超えている場合に機能することに注意してください。

于 2009-01-26T03:04:56.020 に答える
4

あなたのソリューションは問題に対して機能しますが、アルゴリズムは実際には Google が使用するものと同じではありません。負の除数を使用する場合は異なります。

public double GoogleModulo(double value, double divisor)
{
    long q = (long)Math.Floor(value / divisor);
    return value - q * divisor;
}

Console.WriteLine(GoogleModulo(  40,  360)); //   40
Console.WriteLine(GoogleModulo( -40,  360)); //  320
Console.WriteLine(GoogleModulo(-400,  360)); //  320
Console.WriteLine(GoogleModulo(  40, -360)); // -320

ここで最後の計算に対する Google の応答を確認してください。

このアルゴリズムはウィキペディアで説明されており、Donald Knuth によるものです。

于 2009-02-12T14:13:34.217 に答える
3

これにより、必要な結果が得られるはずです

public double Angle {
    get { return _Angle; }
    set { _Angle = value % 360 + (value % 360 < 0 : 360 : 0); }
}

360 は度であり、{0, 360} のどこに角度があるかを見つけようとしていると仮定しています。

于 2009-01-26T03:10:31.343 に答える
2

mod 操作は非常に遅いです。可能であれば、ビット マスクに置き換えます。

coobird のコードはかなり良いですが、mod 操作を行っているため非常に遅いです。データを 2 の累乗の範囲内にスケーリングできる場合は、ビット マスクを使用して速度を約 1 桁 (少なくとも 2 倍または 3 倍速く) 向上させることができます。

C コード:

#define BIT_MASK (0xFFFF)
if (a < 0) {
    return b + (a & BIT_MASK);
} else {
    return a & BIT_MASK;
}

#define を実行時に自由に作成してください。また、必要に応じてビット マスクを 2 の累乗に自由に調整してください。0xFFFFFFFF または 2 のべき乗のように、実装を決定します。

于 2009-04-06T19:47:45.377 に答える
1

// go 'round once

set { _Angle = (value + 360) % 360 }

于 2009-01-26T02:58:10.137 に答える
-1
(360 * Math.floor(Math.abs(value) / 360) + value) % 360
于 2009-01-26T02:59:07.513 に答える
-1

値が大幅に範囲外にならない場合は、少しループすることができます。

while (value < 0) {
  value = value + 360;
}
while (value > 360) {
  value = value - 360;
}
于 2009-01-26T03:02:35.120 に答える