Nodes/ComfyUI-UniversalToolkit/Math Expression (UTK)
ComfyUI Node

Math Expression (UTK)

One node for every calculation — with image width/height and a few tricks

By whmc76·Created about a year ago·Updated about a month ago· 72
Math Expression (UTK)
  • a
  • b
  • c
  • INT
  • FLOAT
expression

ComfyUI's per-operation math nodes (Add, Multiply, Divide…) are fine until you need something that isn't a single operation - say, a weighted formula for CFG, or a resolution computed from two inputs with a rounding step. Math Expression (UTK) is one text box that does the whole job, from ComfyUI-UniversalToolkit. You type an expression, it evaluates it, and you get both an INT and a FLOAT out. It's the "just give me a calculator" node, and once you use it you'll stop wiring three math nodes in series.

How it works

The expression is parsed with Python's ast module and evaluated through a whitelist of operators - not a raw eval(), which is the difference between "a calculator" and "arbitrary code execution." You get the usual arithmetic (+ - * / // % **), bitwise ops, boolean and/or/not, and comparisons (which return 1 or 0, handy for conditional math). Newlines are collapsed so you can paste a multi-line expression without breaking it.

Beyond the operators there's a function list that makes it genuinely useful:

  • round(x, dp), ceil(x), floor(x), sqrt(x), int(x)
  • min(...), max(...) - variadic
  • randomint(min, max), randomchoice(a, b, c, ...)
  • iif(condition, true_val, false_val) - inline if, the one-liner conditional

And the killer feature: if you connect an IMAGE or LATENT into inputs a, b, or c, you can reference a.width and a.height in the expression. That's how you write "canvas width plus a 64px margin" without a size-detection node. Internally it walks the AST, looks up a/b/c, and for images returns the tensor's spatial dims (latents get multiplied by 8 to recover pixel size).

If randomint or randomchoice appears in your expression, the node marks itself as always-changed, so it re-rolls every execution instead of caching. That's a thoughtful detail - otherwise ComfyUI would cache the result and you'd get the same "random" number forever.

Inputs and outputs

  • expression (STRING, multiline) - the math. Required.
  • a, b, c - optional inputs of any type, mostly useful via .width/.height.

Outputs: INT and FLOAT - the same value in both formats, so you don't need a cast node. It's an output node, so the result also shows in the UI.

Install and gotchas

Install via ComfyUI Manager (search "ComfyUI-UniversalToolkit") or:

cd ComfyUI/custom_nodes
git clone https://github.com/whmc76/ComfyUI-UniversalToolkit
pip install -r requirements.txt

Restart ComfyUI. No models, no keys, stdlib only.

Gotchas: variables other than a/b/c don't exist - if you try x it raises "Name not found." Referencing an image by name without .width/.height errors on purpose ("complex types need to reference their width/height"), so remember the dot-suffix. And comparisons return integers, not booleans - 1 if a>b else 0 is the same as a > b here, so use whichever reads better. If your expression throws, the error message names the exact function or operator, which keeps debugging quick.

CategoryUniversalToolkit/Tools

Inputs (4)

NameTypeDefaultDescription
expressionSTRING
aopt*
bopt*
copt*

Outputs (2)

NameTypeDescription
INTINT
FLOATFLOAT