Có toán tử lũy thừa trong C # không?


194

Ví dụ, một toán tử tồn tại để xử lý này?

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Number1 (operator) Number2;

Trước đây, ^toán tử đã từng là toán tử theo cấp số nhân trong các ngôn ngữ khác, nhưng trong C #, nó là toán tử bit khôn ngoan.

Tôi có phải viết một vòng lặp hoặc bao gồm một không gian tên khác để xử lý các hoạt động theo cấp số nhân không? Nếu vậy, làm thế nào để tôi xử lý các hoạt động theo cấp số nhân bằng cách không sử dụng số nguyên?


7
Nó không có trong C #, nhưng nhiều ngôn ngữ sử dụng **làm toán tử lũy thừa infix.
Đánh dấu Rushakoff

đã đến đây bởi vì tôi đã nhận ra rằng 10 ^ 7 được lưu trữ trong một thời gian dài / Int64 đã cho tôi "13." Tôi cũng đã thử 1E7, nhưng điều đó cho tôi một lỗi loại. Vì tôi không thấy lỗi loại / lỗi cú pháp toán tử bất hợp pháp, tôi đã cho rằng 10 ^ 7 của tôi đang hoạt động ...
mpag

1
@mpag ^ là độc quyền hoặc nhà điều hành, vì vậy 10 ^ 7 = 1010b XOR 0111b = 1101b = 13.
Ian Brockbank

Câu trả lời:


227

Ngôn ngữ C # không có toán tử công suất . Tuy nhiên, .NET Framework cung cấp phương thức Math.Pow :

Trả về một số được chỉ định nâng lên công suất được chỉ định.

Vì vậy, ví dụ của bạn sẽ như thế này:

float Result, Number1, Number2;

Number1 = 2;
Number2 = 2;

Result = Math.Pow(Number1, Number2);

1
Hãy ghi nhớ hình phạt hiệu suất nếu sử dụng Math.Pow cho bình phương: stackoverflow.com/questions/936541/iêu
Justas

4
@Justas Tôi chỉ kiểm tra rằng trên .NET Core 2.1 và Math.Pow hiện nhanh hơn so với triển khai thay thế được đề xuất.
bytedev

50

Tôi tình cờ thấy bài này tìm cách sử dụng ký hiệu khoa học trong mã của tôi, tôi đã sử dụng

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

Nhưng sau đó tôi phát hiện ra bạn có thể làm

4.95E-10;

Chỉ cần nghĩ rằng tôi sẽ thêm điều này cho bất cứ ai trong tình huống tương tự mà tôi đang ở.


34

Có một bài đăng trên blog về MSDN về lý do tại sao một toán tử lũy thừa KHÔNG tồn tại từ nhóm C #.

Có thể thêm toán tử năng lượng vào ngôn ngữ, nhưng thực hiện thao tác này là một điều khá hiếm khi thực hiện trong hầu hết các chương trình và dường như không hợp lý khi thêm toán tử khi gọi Math.Pow () là đơn giản.


Bạn đã hỏi:

Tôi có phải viết một vòng lặp hoặc bao gồm một không gian tên khác để xử lý các hoạt động theo cấp số nhân không? Nếu vậy, làm thế nào để tôi xử lý các hoạt động theo cấp số nhân bằng cách không sử dụng số nguyên?

Math.Pow hỗ trợ các tham số kép, do đó bạn không cần phải tự viết.


24
Tôi hiểu đối số, nhưng một lý do hợp lệ là Math.Pow () không thể được sử dụng để đặt giá trị const, điều này làm cho số mũ không thể sử dụng được cho tất cả các hằng.
jsmars

1
Toán tử công suất sẽ thuận tiện cho quá tải toán tử, với tôi Math.Pow () không chứng minh rằng thực tế không tạo toán tử lũy thừa như Math.Pow () không phải là toán tử do đó không sử dụng giống như toán tử ._ .
Alexandre Daubricourt

8

Việc thiếu một toán tử hàm mũ cho C # là một sự phiền toái lớn đối với chúng tôi khi tìm kiếm một ngôn ngữ mới để chuyển đổi phần mềm tính toán của chúng tôi từ ol 'vb6 tốt.

Tôi rất vui vì chúng tôi đã đi với C # nhưng nó vẫn làm tôi khó chịu mỗi khi tôi viết một phương trình phức tạp bao gồm số mũ. Phương thức Math.Pow () làm cho các phương trình khá khó đọc IMO.

Giải pháp của chúng tôi là tạo ra một lớp DoubleX đặc biệt nơi chúng tôi ghi đè ^ -operator (xem bên dưới)

Điều này hoạt động khá tốt miễn là bạn khai báo ít nhất một trong các biến là DoubleX:

DoubleX a = 2;
DoubleX b = 3;

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

hoặc sử dụng một trình chuyển đổi rõ ràng trên đôi tiêu chuẩn:

double c = 2;
double d = 3;

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

Một vấn đề với phương pháp này là số mũ được tính theo thứ tự sai so với các toán tử khác. Điều này có thể tránh được bằng cách luôn đặt thêm () xung quanh thao tác, điều này khiến cho việc đọc các phương trình khó hơn một chút:

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

Tôi hy vọng điều này có thể giúp ích cho những người khác sử dụng nhiều phương trình phức tạp trong mã của họ và có lẽ ai đó thậm chí còn có ý tưởng về cách cải thiện phương pháp này?! :-)

Lớp 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

Tôi ngạc nhiên không ai đề cập đến điều này, nhưng đối với trường hợp bình phương đơn giản (và có lẽ gặp phải nhiều nhất), bạn chỉ cần nhân nó lên.

float Result, Number1;

Result = Number1 * Number1;

4
nó không nhân, sức mạnh của nó.
Henry

Có @Henry và như những người khác đã đề cập, một toán tử không tồn tại. Chỉ cần Math.Pow. Tôi chỉ đưa ra một giải pháp rõ ràng cho trường hợp phổ biến nhất.
RubberDuck

4
Cũng nhanh hơn nhiều so vớiMath.Pow(Number1, 2)
lamont

2

Vì chưa ai viết một hàm để làm điều này với hai số nguyên, nên đây là một cách:

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

Hoặc trong 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

Ai đó có thể vui lòng giải thích các downvote? Tôi đã kiểm tra mã này và bạn cũng có thể tại ideone.com/o9mmAo (C #) & ideone.com/vnaczj (VB.NET) - nó có vẻ hoạt động hoàn hảo.
Nathangrad

8
Vì có Math.Pow nên mã của bạn không liên quan
Thaina

1
Math.Pow () khá chậm và điều này sẽ nhanh hơn đáng kể miễn là PowerOf khá nhỏ.
lamont

3
@Nathangrad Phát minh lại bánh xe (vuông) phần lớn được coi là một mô hình chống. FYI: ngoại
lệfound.net / từ

Ngoài ra, đó là những cách nhanh hơn để thực hiện phương pháp sức mạnh của riêng bạn. Xem: vi.wikipedia.org/wiki/Exponentiation_by_squared
Jesse Chisholm

0

Một chức năng năng lượng tốt sẽ là

    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;
        }
    }

Hàm `Math.Pow` sử dụng chức năng nguồn của bộ xử lý và hiệu quả cao hơn.


0

Đối với những gì đáng giá, tôi bỏ lỡ toán tử ^ khi tăng công suất 2 để xác định hằng số nhị phân. Không thể sử dụng Math.Pow () ở đó, nhưng chuyển một số nguyên không dấu 1 sang trái bởi giá trị của số mũ hoạt động. Khi tôi cần xác định hằng số (2 ^ 24) -1:

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

Hãy nhớ các loại phải là (uint) << (int).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.