C#中有指数运算符吗?

Posted

技术标签:

【中文标题】C#中有指数运算符吗?【英文标题】:Is there an exponent operator in C#? 【发布时间】:2011-03-03 08:28:08 【问题描述】:

例如,是否存在运营商来处理这个问题?

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Number1 (operator) Number2;

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

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

【问题讨论】:

它不是 C# 中的,但许多语言使用 ** 作为中缀求幂运算符。 来到这里是因为我很生气存储在 long/Int64 中的 10 ^ 7 给了我“13”。我也尝试过 1E7,但这给了我一个类型错误。因为我没有看到类型错误/非法运算符语法错误,所以我假设我的 10^7 正在工作...... @mpag ^ 是异或运算符,所以 10^7 = 1010b XOR 0111b = 1101b = 13。 C、C++ 和 C# 没有指数运算符。他们使用 symbol ^ 进行按位异或,因此将 ^ 重载为求幂似乎是不明智的(尽管 BASIC 的悠久传统)。如果有人想添加一个幂运算符,其他选择也有好处。 • FORTRAN 的** 是明智的,因为求幂是“乘法之后的级别”(*)。 • Knuth 的 是合理的,因为求幂是“四分法之前的水平”(↑↑)。 (每种可能性都有优点和缺点(和历史)。)见en.wikipedia.org/wiki/Exponentiation#In_programming_languages 【参考方案1】:

它不是运算符,但您可以编写自己的扩展函数。

public static double Pow(this double value, double exponent)

    return Math.Pow(value, exponent);

这让你可以写

a.Pow(b);

而不是

Math.Pow(a, b);

我认为这使 a 和 b 之间的关系更加清晰 + 你避免一遍又一遍地写“数学”。

【讨论】:

【参考方案2】:

由于还没有人编写一个函数来处理两个整数,所以这里有一种方法:

private static long CalculatePower(int number, int powerOf)

    long result = number;
    for (int i = 2; i <= powerOf; i++)
        result *= number;
    return result;

或者在 VB.NET 中:

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

【讨论】:

有人可以解释一下否决票吗?我已经测试了这段代码,你也可以在 ideone.com/o9mmAo (C#) 和 ideone.com/vnaczj (VB.NET) 上测试 - 它似乎工作得很好。 因为有 Math.Pow 所以你的代码是无关紧要的 Math.Pow() 很慢,只要 PowerOf 相当小,这将大大加快。 @Nathangrad 重新发明(方形)***在很大程度上被认为是一种反模式。仅供参考:exceptionnotfound.net/… 真的需要VB .NET版本吗??因为 VB .NET 已经有了指数运算符...【参考方案3】:

我很惊讶没有人提到这一点,但对于简单的(可能是最常见的)平方的情况,你只需乘以它自己。

float someNumber;

float result = someNumber * someNumber;

【讨论】:

它不是乘法,而是它的幂。 是的@Henry,正如其他人所提到的,运营商不存在。只是Math.Pow。我只是为最常见的情况提供了一个明显的解决方案。 也比Math.Pow(Number1, 2)快很多【参考方案4】:

当我们在寻找一种新语言来将我们的计算软件从优秀的 ol' 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 --------------
    

【讨论】:

【参考方案5】:

一个好的幂函数应该是

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函数使用处理器功率函数,效率更高。

【讨论】:

【参考方案6】:

C# 团队有一个blog post on MSDN about why an exponent operator does NOT exists。

可以添加一个电源 语言的运算符,但是 执行此操作是一个相当 在大多数程序中很少做的事情,并且 添加一个似乎没有道理 调用 Math.Pow() 时的运算符是 很简单。


你问:

我必须写一个循环还是包含 另一个要处理的命名空间 指数运算?如果是这样,怎么办 我使用处理指数运算 非整数?

Math.Pow支持双参数,不用你自己写。

【讨论】:

我理解这个论点,但一个正当的理由是 Math.Pow() 不能用于设置 const 值,这使得指数不能用于所有常量。 幂运算符将便于运算符重载,对我来说 Math.Pow() 并不能证明不创建指数运算符的事实,因为 Math.Pow() 不是运算符,因此没有与运算符相同的用法._. 在 C# 中编写 Unity 游戏时,这是一件相当常见的事情,而当您想要的只是整数的整数幂(如 2^X 或 X^)时,花在双精度求幂上的时间被浪费了2 或 X^3 或类似的东西。我一直都需要它。 我不介意需要更长的时间,但 Math.Pow 使用不精确的双精度数。对转换为双精度的整数值进行简单的加法可以得到类似 n-1.99999999999742 的值,然后将其截断为整数并得到 n-1 而不是 n。【参考方案7】:

C# 语言doesn't have a power operator。但是,.NET Framework 提供了Math.Pow 方法:

返回指定数字的指定幂。

所以你的例子应该是这样的:

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Math.Pow(Number1, Number2);

【讨论】:

如果使用 Math.Pow 进行平方,请记住性能损失:***.com/questions/936541/… @Justas 我刚刚在 .NET Core 2.1 上进行了测试,Math.Pow 现在比建议的替代实现更快。 在尝试调试为什么我的计算不能使用 ^ 但是你仍然不能使用它来定义常量,因为它们必须在编译时定义,Math.Pow() 在运行时使用。 正如@z33k 所说,没有常量也意味着没有枚举。这很可悲,因为它使 Flags Enums 更易于阅读。【参考方案8】:

为了定义二进制常量,我确实错过了 ^ 运算符,因为它是 2 的幂。不能在那里使用 Math.Pow() ,但是将无符号整数 1 向左移动指数值是可行的。当我需要定义 (2^24)-1 的常数时:

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

记住类型必须是 (uint)

【讨论】:

对于小数字(如标志枚举),您可以简单地使用 0 -> 0 | 1 -> 1 1 1 【参考方案9】:

我偶然发现这篇文章希望在我的代码中使用科学记数法,我使用了

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

但后来我发现你可以做到

4.95E-10;

只是想我会为与我遇到类似情况的任何人添加此内容。

【讨论】:

请记住,E 始终是以 10 为底的指数。我知道如果我们仔细观察,我们会理解这一点,但由于 OP 是关于一般指数的,我认为它值得强调。

以上是关于C#中有指数运算符吗?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 中的指数运算符

您可以在 C# 本地函数中使用三元运算符吗?

我应该避免使用 C#“is”运算符进行相等检查吗? [关闭]

C# 中的重载运算符实际上是一种好习惯吗? [关闭]

Python中有“不等于”运算符吗?

C语言中有范围解析运算符吗?