Math Expression node cheatsheet
- Dominant language
- Python
- Stars
- 133k
- Forks
- 15.7k
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 155
Description
I just discovered the comfy native implementation of a math expression node and noticed that it differed in many ways to Pythongosssss' math expression node I used before. Looking for some documentation on it by searching the issues didn't turn up any, so I summarized the functions and syntax with AI help, in case anyone stumbles upon the same issue.
**Note** that I didn't test every single function and this is not official documentation.
If you notice any inaccuracies or find additional functionalities not yet listed, feel free to comment so I can update the markdown
You can copy/paste the markdown below right into a markdown note node to keep as a cheatsheet:
Rendered markdown
# ๐งฎ ComfyUI โ Math Expression Node Cheatsheet
- **Node:** `Math Expression` (`ComfyMathExpression`) ยท Category: *utilities*
- **Engine:** [`simpleeval`](https://github.com/danthedeckie/simpleeval) (safe Python-expression evaluator)
- **Outputs:** `FLOAT`, `INT`, `BOOL` โ all three are produced from every result.
> The expression must evaluate to a **finite number** (int, float, or bool). Strings or other types throw an error.
---
## Variables
| Name | What it is | Notes |
|------|------------|-------|
| `a`, `b`, `c`, โฆ `z` | Your dynamic inputs | Auto-named in order, lowercase aโz. At least **one** (`a`) is required. Each can be FLOAT, INT, or BOOL. |
| `values` | A **list of all inputs** | Handy for `sum(values)`, `max(values)`, `min(values)`. |
| `True` / `False` / `None` | Literals | Work as written. (`None` will fail the numeric check if returned.) |
> โ ๏ธ No `pi`, `e`, or `tau` constants exist. Type the number, or `pi โ 3.141592653589793`.
---
## Functions
| Function | Signature | Does | Example โ Result |
|----------|-----------|------|------------------|
| `sum` | `sum(values)` or `sum(a,b,c)` | Adds a list **or** loose args | `sum(values)` โ all inputs added |
| `min` | `min(a, b, โฆ)` / `min(values)` | Smallest | `min(3, 7)` โ `3` |
| `max` | `max(a, b, โฆ)` / `max(values)` | Largest | `max(3, 7)` โ `7` |
| `abs` | `abs(x)` | Absolute value | `abs(-5)` โ `5` |
| `round` | `round(x[, ndigits])` | Round (banker's rounding) | `round(3.14159, 4)` โ `3.1416` |
| `pow` | `pow(base, exp)` | Power (exp capped at **4000**) | `pow(2, 10)` โ `1024` |
| `sqrt` | `sqrt(x)` | Square root | `sqrt(16)` โ `4.0` |
| `ceil` | `ceil(x)` | Round **up** | `ceil(2.1)` โ `3` |
| `floor` | `floor(x)` | Round **down** | `floor(2.9)` โ `2` |
| `log` | `log(x[, base])` | Natural log, or log to `base` | `log(8, 2)` โ `3.0` |
| `log2` | `log2(x)` | Log base 2 | `log2(8)` โ `3.0` |
| `log10` | `log10(x)` | Log base 10 | `log10(1000)` โ `3.0` |
| `sin` | `sin(x)` | Sine โ **radians!** | `sin(0)` โ `0.0` |
| `cos` | `cos(x)` | Cosine โ **radians!** | `cos(0)` โ `1.0` |
| `tan` | `tan(x)` | Tangent โ **radians!** | `tan(0)` โ `0.0` |
| `int` | `int(x)` | To integer (**truncates toward 0**) | `int(3.9)` โ `3`, `int(-3.9)` โ `-3` |
| `float` | `float(x)` | To float | `float(5)` โ `5.0` |
> ๐ **Degrees โ radians:** `sin(a * 3.141592653589793 / 180)`
---
## Operators
| Group | Operators | Notes |
|-------|-----------|-------|
| Arithmetic | `+` `-` `*` `/` `//` `%`, `**` | `//` floor-div (`7//2` โ `3`); `**` power |
| Comparison | `==` `!=` `>` `<` `>=` `<=` | Return a bool |
| Chained | `0 < a < 10` | โ
Supported โ true only if both hold |
| Boolean | `and`, `or`, `not` | Python truthiness (`a and b` returns `b` if `a` is truthy) |
| Membership | `in`, `not in` | e.g. `a in values` |
| Bitwise | `&` `\|` `^` `~` `<<` `>>` | Integers only |
| Ternary | `x if cond else y` | See below ๐ |
---
## Conditionals
Use Python's inline `if`/`else`:
| Pysssss' node syntax | Comfy Core (native) |
|---------------|--------------|
| `iif(c==1, a, b)` | `a if c == 1 else b` |
| `iif(a>b, a, b)` | `a if a > b else b` *(or just `max(a, b)`)* |
| nested `iif(a>b, a, iif(b>c, b, c))` | `a if a > b else (b if b > c else c)` *(or `max(a, b, c)`)* |
Pattern: **`` `if` `` `else` ``**
---
## Outputs explained
Every run returns all three at once:
| Output | How it's derived | Example (result = `3.7`) |
|--------|------------------|--------------------------|
| `FLOAT` | the raw result as float | `3.7` |
| `INT` | `int(result)` โ **truncates toward zero**, not rounding | `3` |
| `BOOL` | `bool(result)` โ `False` only if `0`/`0.0` | `True` |
> Need proper rounding into INT? Do it in the expression: `round(a / b)`.
> A comparison like `a > b` returns a bool โ `BOOL` = `True/False`, `INT` = `1/0`.
---
## Gotchas & limits
- **No randomness.** `rand()` / `randint()` from the old node are **not** available here.
- **No `str()`** and no string results โ output must be numeric.
- **No node-name references.** Unlike the pysssss node, you can't pull `SomeNode.width`. Only the lettered inputs + `values`.
- **Trig is radians**, not degrees.
- **Result must be finite.** Division by zero, infinity, or NaN throws an error.
- **Exponent caps:** `pow()` exponent โค 4000; the `**` operator is capped much higher (~4M) by the engine.
- **Empty expression** = error.
Pure markdown to copy/paste
```
# ๐งฎ ComfyUI โ Math Expression Node Cheatsheet
- **Node:** `Math Expression` (`ComfyMathExpression`) ยท Category: *utilities*
- **Engine:** [`simpleeval`](https://github.com/danthedeckie/simpleeval) (safe Python-expression evaluator)
- **Outputs:** `FLOAT`, `INT`, `BOOL` โ all three are produced from every result.
> The expression must evaluate to a **finite number** (int, float, or bool). Strings or other types throw an error.
---
## Variables
| Name | What it is | Notes |
|------|------------|-------|
| `a`, `b`, `c`, โฆ `z` | Your dynamic inputs | Auto-named in order, lowercase aโz. At least **one** (`a`) is required. Each can be FLOAT, INT, or BOOL. |
| `values` | A **list of all inputs** | Handy for `sum(values)`, `max(values)`, `min(values)`. |
| `True` / `False` / `None` | Literals | Work as written. (`None` will fail the numeric check if returned.) |
> โ ๏ธ No `pi`, `e`, or `tau` constants exist. Type the number, or `pi โ 3.141592653589793`.
---
## Functions
| Function | Signature | Does | Example โ Result |
|----------|-----------|------|------------------|
| `sum` | `sum(values)` or `sum(a,b,c)` | Adds a list **or** loose args | `sum(values)` โ all inputs added |
| `min` | `min(a, b, โฆ)` / `min(values)` | Smallest | `min(3, 7)` โ `3` |
| `max` | `max(a, b, โฆ)` / `max(values)` | Largest | `max(3, 7)` โ `7` |
| `abs` | `abs(x)` | Absolute value | `abs(-5)` โ `5` |
| `round` | `round(x[, ndigits])` | Round (banker's rounding) | `round(3.14159, 4)` โ `3.1416` |
| `pow` | `pow(base, exp)` | Power (exp capped at **4000**) | `pow(2, 10)` โ `1024` |
| `sqrt` | `sqrt(x)` | Square root | `sqrt(16)` โ `4.0` |
| `ceil` | `ceil(x)` | Round **up** | `ceil(2.1)` โ `3` |
| `floor` | `floor(x)` | Round **down** | `floor(2.9)` โ `2` |
| `log` | `log(x[, base])` | Natural log, or log to `base` | `log(8, 2)` โ `3.0` |
| `log2` | `log2(x)` | Log base 2 | `log2(8)` โ `3.0` |
| `log10` | `log10(x)` | Log base 10 | `log10(1000)` โ `3.0` |
| `sin` | `sin(x)` | Sine โ **radians!** | `sin(0)` โ `0.0` |
| `cos` | `cos(x)` | Cosine โ **radians!** | `cos(0)` โ `1.0` |
| `tan` | `tan(x)` | Tangent โ **radians!** | `tan(0)` โ `0.0` |
| `int` | `int(x)` | To integer (**truncates toward 0**) | `int(3.9)` โ `3`, `int(-3.9)` โ `-3` |
| `float` | `float(x)` | To float | `float(5)` โ `5.0` |
> ๐ **Degrees โ radians:** `sin(a * 3.141592653589793 / 180)`
---
## Operators
| Group | Operators | Notes |
|-------|-----------|-------|
| Arithmetic | `+` `-` `*` `/` `//` `%`, `**` | `//` floor-div (`7//2` โ `3`); `**` power |
| Comparison | `==` `!=` `>` `<` `>=` `<=` | Return a bool |
| Chained | `0 < a < 10` | โ
Supported โ true only if both hold |
| Boolean | `and`, `or`, `not` | Python truthiness (`a and b` returns `b` if `a` is truthy) |
| Membership | `in`, `not in` | e.g. `a in values` |
| Bitwise | `&` `\|` `^` `~` `<<` `>>` | Integers only |
| Ternary | `x if cond else y` | See below ๐ |
---
## Conditionals
Use Python's inline `if`/`else`:
| Pysssss' node syntax | Comfy Core (native) |
|---------------|--------------|
| `iif(c==1, a, b)` | `a if c == 1 else b` |
| `iif(a>b, a, b)` | `a if a > b else b` *(or just `max(a, b)`)* |
| nested `iif(a>b, a, iif(b>c, b, c))` | `a if a > b else (b if b > c else c)` *(or `max(a, b, c)`)* |
Pattern: **`` `if` `` `else` ``**
---
## Outputs explained
Every run returns all three at once:
| Output | How it's derived | Example (result = `3.7`) |
|--------|------------------|--------------------------|
| `FLOAT` | the raw result as float | `3.7` |
| `INT` | `int(result)` โ **truncates toward zero**, not rounding | `3` |
| `BOOL` | `bool(result)` โ `False` only if `0`/`0.0` | `True` |
> Need proper rounding into INT? Do it in the expression: `round(a / b)`.
> A comparison like `a > b` returns a bool โ `BOOL` = `True/False`, `INT` = `1/0`.
---
## Gotchas & limits
- **No randomness.** `rand()` / `randint()` from the old node are **not** available here.
- **No `str()`** and no string results โ output must be numeric.
- **No node-name references.** Unlike the pysssss node, you can't pull `SomeNode.width`. Only the lettered inputs + `values`.
- **Trig is radians**, not degrees.
- **Result must be finite.** Division by zero, infinity, or NaN throws an error.
- **Exponent caps:** `pow()` exponent โค 4000; the `**` operator is capped much higher (~4M) by the engine.
- **Empty expression** = error.
```
Contributor guide
Research direction
Start by locating the native Math Expression node, ComfyMathExpression, and its simpleeval-based implementation; compare the listed variables, functions, operators, outputs, and limits with the actual behavior. Add the verified cheatsheet to the project's appropriate documentation location, and consider the work done when the documented syntax is accurate and useful to users comparing it with the older node.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100