首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 算術運算子與算術運算式:五大運算子、求值順序、餘數運算特性全解析

     編輯:關於C#

算術運算子是程式計算的基石。C# 提供五大運算子 (+, -, *, /, %),支援整數、浮點數、十進位數與使用者定義型別 (透過多載)。理解求值順序、溢位行為與餘數運算特性,對數值計算正確性至關重要。

五大運算子速覽

運算子名稱元數支援類型
+加法二元數值、字串、委派、列舉、TimeSpan
-減法二元/一元數值、委派、列舉、TimeSpan
*乘法二元數值
/除法二元數值
%餘數二元整數、浮點數、十進位數

求值順序:嚴格左至右 (關鍵)

C# 保證運算元與引數由左至右評估,無論運算子優先級:

static void F(int x, int y, int z) 
    => Console.WriteLine($"x={x}, y={y}, z={z}");

int i = 0;
F(i++, i++, i++); 
// 輸出:x=0, y=1, z=2
// 順序:第一個 i++ (值 0, i→1), 第二個 (值 1, i→2), 第三個 (值 2, i→3)

優先級不影響求值順序

int a = 0;
int result = a++ + a++ * a++; 
// 1. 左至右取值:0, 1, 2
// 2. 依優先級計算:0 + (1 * 2) = 2
// 3. 副作用已完成:a = 3

餘數運算 (%) 深度解析

定義關係

// a = (a / b) * b + (a % b)
// 餘數符號與被除數 (a) 相同

整數餘數

5 % 3    // 2
-5 % 3   // -2 (被除數負,餘數負)
5 % -3   // 2  (被除數正,餘數正)
-5 % -3  // -2

浮點數/十進位數餘數 (C# 特有)

5.0 % 3.0    // 2.0
5.0 % 1.5    // 0.5
5.5m % 2.0m  // 1.5m (decimal)

double nan = double.NaN;
nan % 2.0    // NaN
double.PositiveInfinity % 2.0 // NaN

與數學模運算差異

// 數學模:結果永遠非負 (Python 行為)
// C# 餘數:符號跟隨被除數

// 修正為非負模運算
int Mod(int a, int b) 
{
    int r = a % b;
    return r < 0 ? r + Math.Abs(b) : r;
}
// Mod(-5, 3) = 1

溢位與檢查語境

語境整數溢位行為浮點數溢位
unchecked (預設)環繞 (截斷高位)±Infinity
checked拋出 OverflowException±Infinity (不受影響)
常數運算式編譯時期檢查 (永遠 checked)編譯時期計算
// 預設 unchecked:環繞
int max = int.MaxValue;
var wrap = max + 1; // -2147483648 (int.MinValue)

// checked:拋出例外
checked 
{
    var crash = max + 1; // OverflowException
}

// 常數運算式永遠檢查
// const int crash = int.MaxValue + 1; // 編譯錯誤 CS0220

除法運算細節 (補充)

整數除法:截斷向零

5 / 3    // 1
-5 / 3   // -1 (向零截斷,非向下取整)
5 / -3   // -1
-5 / -3  // 1

浮點數除法:IEEE 754

5.0 / 2.0    // 2.5
5.0 / 0.0    // Infinity
-5.0 / 0.0   // -Infinity
0.0 / 0.0    // NaN

decimal 除法:高精度、有限範圍

10.0m / 3.0m // 3.3333333333333333333333333333 (28-29 位有效數字)
1.0m / 0.0m  // DivideByZeroException (decimal 無 Infinity/NaN)

一元正負號

+5     // 5 (無作用,僅為對稱性)
-5     // -5
-( -5) // 5

// 陷阱:最小值取負仍為最小值 (溢位)
int min = int.MinValue; // -2147483648
int neg = -min;         // -2147483648 (環繞,unchecked)
checked { -min; }       // OverflowException

使用者定義型別多載

public readonly struct Vector2
{
    public double X, Y;
    
    public static Vector2 operator +(Vector2 a, Vector2 b) 
        => new Vector2 { X = a.X + b.X, Y = a.Y + b.Y };
    public static Vector2 operator -(Vector2 a, Vector2 b) 
        => new Vector2 { X = a.X - b.X, Y = a.Y - b.Y };
    public static Vector2 operator *(Vector2 a, double k) 
        => new Vector2 { X = a.X * k, Y = a.Y * k };
    public static Vector2 operator /(Vector2 a, double k) 
        => new Vector2 { X = a.X / k, Y = a.Y / k };
    
    // 一元運算子
    public static Vector2 operator -(Vector2 a) 
        => new Vector2 { X = -a.X, Y = -a.Y };
}

最佳實踐總結

  1. 金融/貨幣計算用 decimal — 避免二進位浮點誤差
  2. 科學計算用 double — 範圍大、硬體加速
  3. 整數溢位風險處用 checked — 或 checked 區塊
  4. 餘數運算注意符號規則 — 被除數決定符號,非除數
  5. 除以零:整數拋出例外,浮點數回傳 Infinity/NaN
  6. 依賴求值順序的程式碼需註解 — 雖然語言保證左至右,但易被誤解
  7. 多載運算子遵循數學律 — 交換律、結合律、分配律 (盡可能)

精通算術運算子的求值順序、溢位語境、餘數符號規則與除法細節,是編寫正確數值計算程式的基礎功力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved