C#には指数演算子はありますか?


194

たとえば、これを処理するための演算子は存在しますか?

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Number1 (operator) Number2;

過去に ^他の言語では指数演算子として機能していましたが、C#ではビット単位の演算子です。

指数演算を処理するためにループを作成するか、別の名前空間を含める必要がありますか?もしそうなら、非整数を使用して指数演算をどのように処理しますか?


7
C#にはありませんが、多くの言語**が中置指数演算子として使用されています。
Mark Rushakoff、2014年

ここに来たのは、long / Int64に格納された10 ^ 7が「13」を与えていることに感心しました。1E7も試しましたが、タイプエラーが発生しました。タイプエラー/不正な演算子の構文エラーが表示されなかったので、10 ^ 7が機能していると思っていました...
mpag

1
@mpag ^は排他的OR演算子なので、10 ^ 7 = 1010b XOR 0111b = 1101b = 13
Ian Brockbank

回答:


227

C#言語にはパワー演算子がありません。ただし、.NET FrameworkはMath.Powメソッドを提供します。

指定された指数で指定された数を返します。

したがって、例は次のようになります。

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Math.Pow(Number1, Number2);

1
乗用Math.Powを使用している場合を念頭にパフォーマンスの低下を保管してください:stackoverflow.com/questions/936541/...を
Justas

4
@Justas .NET Core 2.1とMath.Powでテストしたところ、推奨される代替実装よりも高速になりました。
bytedev '19

50

私は自分のコードで科学表記を使用しようとしてこの投稿に出くわしました、私は使用しました

4.95*Math.Pow(10,-10);

しかし、その後私はあなたができることを知りました

4.95E-10;

私がいるのと同じような状況にいる人のためにこれを追加すると思いました。


34

MSDNには、C#チームの指数演算子が存在しない理由に関するブログ投稿があります。

言語にパワー演算子を追加することは可能ですが、この操作を実行することはほとんどのプログラムで行うことはかなりまれなことであり、Math.Pow()を呼び出すときに演算子を追加することは簡単ではありません。


あなたは尋ねました:

指数演算を処理するためにループを作成するか、別の名前空間を含める必要がありますか?もしそうなら、非整数を使用して指数演算をどのように処理しますか?

Math.Powは二重パラメーターをサポートしているため、独自にパラメーターを作成する必要はありません。


24
私は議論を理解していますが、正当な理由は、Math.Pow()を使用してconst値を設定できないため、すべての定数で指数が使用できなくなることです。
jsmars 2014年

1
べき演算子は、演算子のオーバーロードに便利です。私にとって、Math.Pow()は、Math.Pow()が演算子ではないため、演算子と同じ使用法ではないため、指数演算子を作成しないという事実を正当化しません。 。
Alexandre Daubricourt 2018

8

C#の指数演算子がないことは、計算ソフトウェアを優れたol 'vb6から変換するための新しい言語を探す際に、私たちにとって大きな不満でした。

C#を使用して良かったと思いますが、指数を含む複雑な方程式を書いているときはいつでもイライラします。Math.Pow()メソッドは、IMOを読みにくくする方程式を作成します。

私たちの解決策は、^演算子をオーバーライドする特別なDoubleXクラスを作成することでした(以下を参照)

これは、変数の少なくとも1つをDoubleXとして宣言している限り、適切に機能します。

DoubleX a = 2;
DoubleX b = 3;

Console.WriteLine($"a = {a}, b = {b}, a^b = {a ^ b}");

または、標準のdoubleで明示的なコンバーターを使用します。

double c = 2;
double d = 3;

Console.WriteLine($"c = {c}, d = {d}, c^d = {c ^ (DoubleX)d}");     // Need explicit converter

ただし、この方法の1つの問題は、指数が他の演算子と比較して間違った順序で計算されることです。これは、常に演算の周りに余分な()を置くことで回避できます。これにより、方程式を読み取るのが少し難しくなります。

DoubleX a = 2;
DoubleX b = 3;

Console.WriteLine($"a = {a}, b = {b}, 3+a^b = {3 + a ^ b}");        // Wrong result
Console.WriteLine($"a = {a}, b = {b}, 3+a^b = {3 + (a ^ b)}");      // Correct result

これがコードで多くの複雑な方程式を使用する他の人の助けになることを願っています、そして誰かがこの方法を改善する方法のアイデアさえ持っているかもしれません!?:-)

DoubleXクラス:

using System;

namespace ExponentialOperator
{
    /// <summary>
    /// Double class that uses ^ as exponential operator
    /// </summary>
    public class DoubleX
    {
        #region ---------------- Fields ----------------

        private readonly double _value;

        #endregion ------------- Fields ----------------

        #region -------------- Properties --------------

        public double Value
        {
            get { return _value; }
        }

        #endregion ----------- Properties --------------

        #region ------------- Constructors -------------

        public DoubleX(double value)
        {
            _value = value;
        }

        public DoubleX(int value)
        {
            _value = Convert.ToDouble(value);
        }

        #endregion ---------- Constructors -------------

        #region --------------- Methods ----------------

        public override string ToString()
        {
            return _value.ToString();
        }

        #endregion ------------ Methods ----------------

        #region -------------- Operators ---------------

        // Change the ^ operator to be used for exponents.

        public static DoubleX operator ^(DoubleX value, DoubleX exponent)
        {
            return Math.Pow(value, exponent);
        }

        public static DoubleX operator ^(DoubleX value, double exponent)
        {
            return Math.Pow(value, exponent);
        }

        public static DoubleX operator ^(double value, DoubleX exponent)
        {
            return Math.Pow(value, exponent);
        }

        public static DoubleX operator ^(DoubleX value, int exponent)
        {
            return Math.Pow(value, exponent);
        }

        #endregion ----------- Operators ---------------

        #region -------------- Converters --------------

        // Allow implicit convertion

        public static implicit operator DoubleX(double value)
        {
            return new DoubleX(value);
        }

        public static implicit operator DoubleX(int value)
        {
            return new DoubleX(value);
        }

        public static implicit operator Double(DoubleX value)
        {
            return value._value;
        }

        #endregion ----------- Converters --------------
    }
}

2

誰もこれについて言及していないことに驚いていますが、二乗の単純な(そしておそらく最も遭遇する)ケースでは、あなたはそれ自体で乗算します。

float Result, Number1;

Result = Number1 * Number1;

4
その乗算ではなく、その力。
ヘンリー

はい、@ヘンリーと他の人が述べたように、オペレーターは存在しません。ただMath.Pow。私は、最も一般的なケースに対する明白な解決策を提供しているだけでした。
RubberDuck 2017

4
また、はるかに速いMath.Pow(Number1, 2)
lamont

2

まだ2つの整数でこれを行う関数を書いた人はいないので、ここに1つの方法があります。

private long CalculatePower(int number, int powerOf)
{
    for (int i = powerOf; i > 1; i--)
        number *= number;
    return number;
}
CalculatePower(5, 3); // 125
CalculatePower(8, 4); // 4096
CalculatePower(6, 2); // 36

または、VB.NETの場合:

Private Function CalculatePower(number As Integer, powerOf As Integer) As Long
    For i As Integer = powerOf To 2 Step -1
        number *= number
    Next
    Return number
End Function
CalculatePower(5, 3) ' 125
CalculatePower(8, 4) ' 4096
CalculatePower(6, 2) ' 36

誰かが反対票を説明できますか?私はこのコードをテストしましたが、ideone.com / o9mmAo(C#)とideone.com/vnaczj(VB.NETでも同じことができます。完全にうまく機能しているようです。
Nathangrad 2016

8
Math.Powがあるため、コードは不適切です
Thaina

1
Math.Pow()は低速ですが、PowerOfが適度に小さい限り、これはかなり高速になります。
ラモント2017

3
@Nathangrad(正方形)ホイールの再発明は、主にアンチパターンと見なされています。FYI:exceptionnotfound.net/...
bytedev

また、独自のパワーメソッドを実装するより高速な方法もあります。参照:en.wikipedia.org/wiki/Exponentiation_by_squaring
Jesse Chisholm

0

良いべき関数は

    public long Power(int number, int power) {
        if (number == 0) return 0;
        long t = number;
        int e = power;
        int result = 1;
        for(i=0; i<sizeof(int); i++) {
            if (e & 1 == 1) result *= t;
            e >>= 1;
            if (e==0) break;
            t = t * t;
        }
    }

`Math.Pow`関数はプロセッサー能力関数を使用し、非常に効率的です。


0

2の定数を定義するために2の累乗を上げると、^演算子を見逃してしまいます。そこでMath.Pow()を使用することはできませんが、符号なし整数の1を指数の値だけ左にシフトすると機能します。(2 ^ 24)-1の定数を定義する必要がある場合:

public static int Phase_count = 24;
public static uint PatternDecimal_Max = ((uint)1 << Phase_count) - 1;

タイプは(uint)<<(int)でなければならないことに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.