> For the complete documentation index, see [llms.txt](https://docs.myarc.icu/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.myarc.icu/cai-dan-pei-zhi/menus/math-expressions.md).

# 数学表达式

在制作动态商店、升级系统或属性面板时，你经常需要根据玩家输入的数量计算总价、打折取整，并把结果展示在界面上或用于扣款判断。ArcMenu 内置了一套统一的数学表达式引擎，在**条件比较**、**经济与点券动作**以及 **`{math: ...}` 计算占位符**中完全通用。

计算的基本流程很简单：系统会先把表达式里的普通占位符（如 `{meta:input-x}`、`%player_level%`）替换成当前玩家的实际文本，然后再执行数学运算。

## 典型场景：数量 × 单价

假设玩家通过 [Arcitx 文本输入](/gong-neng-pei-zhi/arcitx.md)或加减按钮设置了购买数量 `{meta:input-x}`，每件商品单价为 `24`，我们可以先用条件校验输入数量是否合法，再检查预算是否充足：

```yaml
# 校验数量在 1 到 64 之间，且必须是整数
condition: '{meta:input-x} >= 1 && {meta:input-x} <= 64 && {meta:input-x} == floor({meta:input-x})'
```

接着判断余额是否够付总价（以下用预算 `1000` 演示；实际服务器中请把 `1000` 换成经济插件的占位符，例如 `%vault_eco_balance%`，因为系统没有名为 `money` 的内置变量）：

```yaml
condition: '1000 >= {meta:input-x} * 24'
```

提示：如果购买数量来自 Arcitx 输入框，玩家需要先点击该输入框绑定的提交（`submit`）区域，输入内容才会正式写入 `{meta:input-输入框ID}`。

## 运算符与数字格式

表达式支持整数、小数（如 `24`、`1.5`、`.5`、`5.`）以及科学计数法（如 `1e3`、`1e-3`）。所有乘法都必须显式写出 `*` 号（例如写 `2 * (3 + 4)`，不能省略成 `2(3 + 4)`）。

| 运算符         | 含义与运算规则                           | 写法与结果示例                                            |
| ----------- | --------------------------------- | -------------------------------------------------- |
| `( )`       | 圆括号，最高优先级，用于改变运算顺序。               | `(2 + 3) * 4` → `20`                               |
| `^`         | 乘方（幂运算）。优先级高于正负号，且连续乘方**从右向左**结合。 | `2 ^ 3 ^ 2`（即 $2^{(3^2)}$）→ `512`                  |
| `+`、`-`（一元） | 正号与负号。优先级低于乘方。                    | `-2 ^ 2` → `-4`；`(-2) ^ 2` → `4`；`2 ^ -2` → `0.25` |
| `*`、`/`、`%` | 乘法、除法与取余。`%` 求余数的符号与被除数保持一致。      | `3 * 24` → `72`；`7 % 3` → `1`；`-7 % 3` → `-1`      |
| `+`、`-`（二元） | 加法与减法。                            | `1 - -2` → `3`                                     |

## 内置数学函数

函数名称不区分大小写，多个参数之间用英文逗号 `,` 分隔。函数与运算符可以任意组合嵌套，比如用 `max(1, min(64, floor({meta:input-x})))` 把任意数字限制在 1 到 64 的整数范围内。

| 函数写法               | 参数要求     | 功能说明                                                 | 示例与结果                                   |
| ------------------ | -------- | ---------------------------------------------------- | --------------------------------------- |
| `abs(x)`           | 1 个参数    | 返回 `x` 的绝对值。                                         | `abs(-3.5)` → `3.5`                     |
| `min(x, ...)`      | 1 个或多个参数 | 返回所有参数中的最小值。                                         | `min(5, 2, 8)` → `2`                    |
| `max(x, ...)`      | 1 个或多个参数 | 返回所有参数中的最大值。                                         | `max(1, 3)` → `3`                       |
| `floor(x)`         | 1 个参数    | 向下取整（向负无穷方向取不大于 `x` 的最大整数）。                          | `floor(2.9)` → `2`；`floor(-1.1)` → `-2` |
| `ceil(x)`          | 1 个参数    | 向上取整（向正无穷方向取不小于 `x` 的最小整数）。                          | `ceil(2.1)` → `3`；`ceil(-1.1)` → `-1`   |
| `round(x)`         | 1 个参数    | 四舍五入到整数。遇到 `.5` 半值时，正负数均向**远离零**的方向进位（HALF\_UP）。     | `round(2.5)` → `3`；`round(-2.5)` → `-3` |
| `round(x, places)` | 2 个参数    | 四舍五入并保留 `places` 位小数。`places` 必须填写 `0` 到 `15` 之间的整数。 | `round(2.675, 2)` → `2.68`              |

## 三种使用位置详解

### 1. 在条件（Condition）中直接计算

在[条件](/cai-dan-pei-zhi/menus/conditions.md)的比较符号（`==`、`!=`、`>`、`>=`、`<`、`<=`、`is`、`is not`）两侧，直接写数学表达式即可，不需要套 `{math: ...}`：

```yaml
condition: '1000 >= round({meta:input-x} * 24 * 0.95, 2)'
```

单条动作末尾的 `{condition=...}` 附加选项也完全支持同样的写法：

```yaml
actions:
  right:
    - 'tell: &a数量在预算内。 {condition=1000 >= {meta:input-x} * 24}'
```

注意区分 YAML 外层引号与内部文本引号：外层的单引号 `'...'` 只是 YAML 字符串的边界，不会阻止内部计算；如果你真的想把 `3*4` 当作普通文字而不是算式去比较，请在操作数两边加上反引号，例如 ``condition: '`3*4` == `3*4`'``。

### 2. 在余额与点券动作中直接计算

`give-money`、`take-money`、`set-money`、`give-points`、`take-points` 和 `set-points` 这六个动作的数值参数会直接通过数学引擎求值：

```yaml
actions:
  right:
    - 'take-money: round({meta:input-x} * 24 * 0.95, 2)'
```

这六个动作都要求最终算出的结果**大于 `0`**。Vault 金币支持小数（推荐搭配 `round(算式, 2)` 保留两位小数）；PlayerPoints 点券要求结果必须是整数，打折计算时请用 `floor`、`ceil` 或单参数 `round` 取整。

### 3. 在文本、命令与变量中使用 `{math: ...}`

在前端文本（`content`）、悬浮提示框（`tooltip`）、命令参数或 `set-meta` / `set-data` 等普通字符串位置，系统默认把内容当作普通文字处理。只有在这些地方显式写上 `{math: 表达式}`，系统才会把大括号里的内容算出来并替换成数字文本。

使用前请确保参与计算的变量已经有了数字值（未设置的变量展开后是 `null`，不能直接算乘法）。比如可以在打开商店菜单的入口按钮上先设置初始数量 `set-meta: input-x 1`，然后再打开菜单：

```yaml
frontend:
  total:
    type: text
    content: '&f总价：{math: {meta:input-x} * 24}'
    size: 4
    update: 20

backend:
  calculate:
    width: 60
    height: 18
    actions:
      right:
        - 'set-meta: total {math: {meta:input-x} * 24}'
        - 'tell: &a总价已记录为：{meta:total}'
```

对比下面两种写法的区别：

* `set-meta: total 3 * 24`：保存的是字面文本 `3 * 24`。
* `set-meta: total {math: 3 * 24}`：保存的是计算结果 `72`。

`{math: ...}` 支持多层嵌套（最多 64 层），系统会从最内层向外层依次求值，例如 `{math: {math: 2 + 3} + 9}` 会先算出内层的 `5`，再算出最终结果 `14`。当变量在菜单打开期间发生变化时，前端文本同样需要配置 `update` 周期或通过 `refresh` 动作来更新画面显示，详见[占位符与文字格式](/wen-zi-ge-shi/text-placeholders.md)。

## 计算精度与异常处理

* **显示格式化**：内部运算采用双精度浮点数（Double）。通过 `{math: ...}` 输出为文本时，系统会按 15 位有效数字进行四舍五入，自动去掉末尾多余的 `0`，并且始终输出普通十进制数字（不输出科学计数法）。因此 `{math: 0.1 + 0.2}` 会干净地输出 `0.3`。如果在条件中用 `==` 判断两个复杂小数算式是否相等，建议套上 `round(算式, 小数位)` 以避免微小的浮点尾差。
* **安全限制与报错排查**：除以零、对零取余、结果无穷大（Infinity / NaN）、未知函数名、函数参数个数不对、括号不匹配，或是表达式/占位符嵌套超过 64 层，都会被视为无效表达式：
  * **在条件中**：该条件直接判为 `false`（不通过），并在后台打印具体出错字符位置与原因；即便外面套了 `not`，报错的算式也不会变成通过。
  * **在动作中**：立即停止当前动作链的后续执行（已执行过的动作不会回滚），并在后台记录日志。
  * **在前端文本或编辑器预览中**：会直接提示具体的算式错误位置，方便你快速定位并修正配置。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.myarc.icu/cai-dan-pei-zhi/menus/math-expressions.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
