算术运算

算术运算包括 5 个二进制运算,即加、减、乘、除和模除,以及 2 个一元运算,即正号和负号。下表给出了每种运算使用的符号。

在包含示例的列中,e1e2 是任意子表达式。用左(从左向右)和右(从右向左)标记结合性。第一列中的数字可以被视为执行运算的优先级。

优先级

符号

说明

示例

结合性

2

+

一元加法

+e1

2

-

一元减法

-e1

3

*

乘法

e1 * e2

3

/

除法

e1 / e2

3

%

模除法

e1 % e2

4

+

加法

e1 + e2

4

-

减法

e1 - e2

表中的顺序为降序优先级:一元加法和减法优先于乘法和除法,而乘法和除法优先于加法和减法。

double a = 3 + 4 * 5// a = 23

事实上,一元加法在计算中没有任何作用,但可以用于更好地可视化表达式。一元减法可反转其操作数的符号。

算术运算用于数字类型或可以强制转换为数字类型的类型。计算结果是一个右值。在计算中,整数操作数的存储位置通常会扩展到所用整数中“最大值”或扩展到 int(如果所有整数类型都更小),并被强制转换为一种通用类型。有关更多详细信息,请参见 类型强制转换

bool b1 = true;
bool b2 = -b1;

在本示例中,b1 变量“扩展” 至值为 1 的 int 类型。反转符号得 -1,而类型强制转换为 bool 再反转得到 true(因为 -1 非零)。不建议在算术计算中使用逻辑类型。

整数相除结果为整数,即小数部分(如有)被忽略。可以使用 ExprArithmetic.mq5 脚本验证这一点。

int a = 24 / 7;      // ok: a = 3
int b = 24 / 8;      // ok: b = 3
double c = 24 / 7;   // ok: c = 3 (!)

虽然 c 变量被描述为 double,但是该变量的初始化表达式中包含整数;因此,执行的是整数除法。要执行带小数部分的除法,必须至少有一个操作数是实数类型(第二个操作数也将被强制转换为实数类型)。

double d = 24.0 / 7// ok: d = 3.4285714285714284

% 运算符计算整数除法的余数(仅适用于两个整数类型的操作数)。

int x = 11 % 5;   // ok: x = 1
int y = 11 % 5.0// no real number can be used
                  // error: '%' - illegal operation use

操作数具有不同符号时,使用 * 和 / 运算符的结果为负数。% 运算符遵循以下规则:

  • 如果 % 运算符的除数为负,则符号“转义”;
  • 如果 % 运算符的被除数为负,则结果为负;

使用模除法的替代计算可以轻松验证这一点:m % n = m - m / n * n。切记,整数除法 m / n 的结果将被舍入;所以一般情况下,m / n * n 不等于 m

数组特性一节中,我们深入研究了多维数组可以用一维数组来表示的思想(通过重新计算数组元素的索引)。我们还提供了通过二维数组的坐标(列号为 X,行号为 Y,字符串长度为 N)获得一维数组的查询索引的公式。

index = Y * N + X

% 运算允许我们执行更便捷的反向计算,即通过索引穿透法求解 X 和 Y:

Y = index / N
X = index % N

如果在计算表达式期间的某个阶段获得一个不可表示的结果 NaN(非数字,如无穷大、负数的平方根等),所有后续的运算也会产生一个 NaN。可以使用 MathIsValidNumber 函数判定结果是否为正常数值(参见 数学函数)。

double z = DBL_MAX / DBL_MIN - 1// inf: Not A Number

此处是对 NaN(除法运算的结果)进行了减法运算,结果再次得到 NaN。

为字符串定义加法运算,并执行连接,即组合字符串。

string s = "Hello, " + "world!"// "Hello, World!"

禁止对字符串进行其他运算。