C#中是否有指数运算符?


194

例如,是否存在操作员来处理此问题?

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Number1 (operator) Number2;

过去,该^运算符曾用其他语言作为指数运算符,但在C#中是按位运算符。

我是否必须编写一个循环或包含另一个名称空间来处理指数运算?如果是这样,我该如何使用非整数处理指数运算?


7
它不是C#语言,但是许多语言都**用作中缀指数运算符。
Mark Rushakoff 2010年

来到这里是因为我被惊吓了,存储在long / Int64中的10 ^ 7给了我“ 13”。我也尝试过1E7,但这给了我一个类型错误。由于我没有看到类型错误/非法运算符语法错误,所以我以为我的10 ^ 7可以正常工作……
mpag

1
@mpag ^是异或运算符,所以10 ^ 7 = 1010B XOR 0111b = 1101B = 13
伊恩Brockbank

Answers:


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

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()不是运算符,因此用法与运算符._不相同。 。
亚历山德拉·杜布瑞克

8

在寻找一种将计算软件转换为良好的vb6语言的新语言时,C#缺少指数运算符对我们来说是一个很大的烦恼。

我很高兴我们选择了C#,但是每当我编写包含指数的复杂方程式时,它仍然使我感到烦恼。Math.Pow()方法使方程式很难阅读IMO。

我们的解决方案是创建一个特殊的DoubleX类,在其中重写^ -operator(请参见下文)

只要您将至少一个变量声明为DoubleX,这就能很好地工作:

DoubleX a = 2;
DoubleX b = 3;

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

或在标准双打上使用显式转换器:

double c = 2;
double d = 3;

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

但是,此方法的一个问题是,与其他运算符相比,指数的计算顺序错误。可以通过始终在操作周围放置一个多余的()来避免这种情况,这又使读取等式变得更加困难:

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
它不是乘法,就是它的力量。
亨利

是的,@ Henry和其他人提到的那样,运算符不存在。只是Math.Pow。我只是为最常见的情况提供了一个显而易见的解决方案。
RubberDuck

4
比也快得多Math.Pow(Number1, 2)
拉蒙特

2

由于尚无人编写过函数来使用两个整数来执行此操作,因此这是一种方法:

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)上使用-它似乎运行得很好。
内森格拉德'16

8
因为有Math.Pow,所以您的代码无关紧要
Thaina

1
不过Math.Pow()速度很慢,只要PowerOf相当小,它的速度就会大大加快。
lamont

3
@Nathangrad重塑(方形)轮子在很大程度上被认为是一种反模式。仅供参考: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的幂以定义二进制常量时,我​​确实会错过^运算符。不能在此处使用Math.Pow(),但可以将指数值向左移动无符号整数1到位。当我需要定义(2 ^ 24)-1的常量时:

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

记住类型必须是(uint)<<(int)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.