You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.5 KiB
106 lines
3.5 KiB
# `math`
|
|
|
|
`a` keeps Lua's standard `math` library intact and adds a handful of functions
|
|
that come up constantly in everyday scripting: rounding, clamping, sign, finiteness,
|
|
and linear rescaling. The additions live on the same global `math` table, so
|
|
`math.floor` and `math.round` sit side by side.
|
|
|
|
```lua
|
|
print(math.round(3.14159, 2)) --> 3.14
|
|
print(math.clamp(120, 0, 100)) --> 100
|
|
print(math.scale(0.5, 0, 1, 0, 255)) --> 127.5
|
|
```
|
|
|
|
Everything here errors on a non-number argument rather than coercing it, so a
|
|
stray `nil` or string surfaces at the call site instead of producing a silent
|
|
`NaN`.
|
|
|
|
## `math.round(value [, places])`
|
|
|
|
Round to the nearest integer, or to `places` decimal places. Rounding is **half
|
|
away from zero** (so `0.5` → `1`, `-0.5` → `-1`), computed exactly — it does not
|
|
suffer the `floor(x + 0.5)` error that mis-rounds values just under `.5`.
|
|
|
|
The return *type* depends on `places`:
|
|
|
|
- `places` omitted or `0` → an **integer**,
|
|
- `places > 0` → a **float** rounded to that many decimals.
|
|
|
|
```lua
|
|
math.round(2.5) --> 3 (integer)
|
|
math.round(-2.5) --> -3
|
|
math.round(3.14159, 2) --> 3.14 (float)
|
|
math.round(7) --> 7 (integers pass through)
|
|
```
|
|
|
|
`places` must be a non-negative integer. A non-finite `value` (`NaN`/infinity) or
|
|
a result outside Lua's integer range is an error.
|
|
|
|
## `math.clamp(value, min, max)`
|
|
|
|
Constrain `value` to the interval `[min, max]`. Either bound may be `nil` to
|
|
leave that side open:
|
|
|
|
```lua
|
|
math.clamp(15, 0, 10) --> 10
|
|
math.clamp(-3, 0, 10) --> 0
|
|
math.clamp(5, 0, 10) --> 5
|
|
math.clamp(-3, 0, nil) --> 0 (no upper bound)
|
|
math.clamp(99, nil, 10) --> 10 (no lower bound)
|
|
```
|
|
|
|
It is an error for `min` to exceed `max`.
|
|
|
|
## `math.isFinite(value)`
|
|
|
|
Return `true` if `value` is a number that is neither `NaN` nor infinite. Anything
|
|
that is not a number returns `false` (it does not error), making it a safe guard
|
|
before arithmetic:
|
|
|
|
```lua
|
|
math.isFinite(1.5) --> true
|
|
math.isFinite(1/0) --> false (infinity)
|
|
math.isFinite(0/0) --> false (NaN)
|
|
math.isFinite("x") --> false
|
|
```
|
|
|
|
## `math.sign(value)`
|
|
|
|
Return the sign of a number as `-1`, `0`, or `1`. Zero (and `NaN`) yield `0`.
|
|
|
|
```lua
|
|
math.sign(-42) --> -1
|
|
math.sign(0) --> 0
|
|
math.sign(3.5) --> 1
|
|
```
|
|
|
|
## `math.scale(value, inMin, inMax, outMin, outMax [, clamp])`
|
|
|
|
Linearly remap `value` from the input range `[inMin, inMax]` onto the output
|
|
range `[outMin, outMax]`. With `clamp = true`, the result is held within the
|
|
output range for inputs that fall outside the input range.
|
|
|
|
```lua
|
|
-- map a 0–1023 ADC reading to a 0–100 percentage
|
|
math.scale(512, 0, 1023, 0, 100) --> ~50.05
|
|
|
|
-- ranges may descend, and you can invert
|
|
math.scale(0, 0, 100, 100, 0) --> 100
|
|
|
|
-- clamp keeps out-of-range inputs inside the output band
|
|
math.scale(2.0, 0, 1, 0, 255) --> 510 (unclamped)
|
|
math.scale(2.0, 0, 1, 0, 255, true) --> 255 (clamped)
|
|
```
|
|
|
|
The input range cannot be empty — `inMin == inMax` is an error (it would divide
|
|
by zero).
|
|
|
|
## Notes
|
|
|
|
- **Additions, not replacements.** All of stock Lua's `math` — `floor`, `ceil`,
|
|
`abs`, `min`, `max`, `sqrt`, `huge`, `pi`, `tointeger`, `type`, … — is still
|
|
there unchanged.
|
|
- **`round` is the only type-changing one.** It returns an integer for
|
|
`places == 0` and a float otherwise; the rest return whatever fits naturally.
|
|
- **Aggregates over tables live in [`table`](table.md).** For the min/max/mean/sum
|
|
of a collection, see `table.min`, `table.max`, `table.mean`, `table.sum`.
|
|
|