# Trigonometry and probability
> Sine, cosine, tangent and their inverses, hyperbolic functions, and the normal distribution (chance, bell height and inverse).
- Category: Functions — math
- Keywords: trigonometry, angle, radian, degree, circle, cycle, wave, seasonality, sine, cosine, tangent, cotangent, arc sine, arcsin, arc cosine, arccos, arc tangent, arctan, arctan2, trend angle, hyperbolic, squash, fisher transform, normal distribution, bell curve, gaussian, probability, chance, z-score, cumulative distribution, norm.dist, NORMSDIST, density, norm.inv, NORMSINV, quantile of normal, confidence level
- See also: [Math functions](functions-math.md), [Statistics functions](functions-statistics.md), [Returns and risk](functions-returns-risk.md), [Finance and price functions](functions-finance.md)
These functions work with **angles** and with **chances**.
**Angles.** An angle can be measured in **degrees** (a full circle is 360°) or in **radians** (a full circle is 2π, about 6.28). All functions here use **radians**. Change degrees to radians with [radians](functions-math.md#radians), and back with [degrees](functions-math.md#degrees): `sin(radians(30))` is `0.5`.
**Rules**
- A `NULL` argument gives `NULL`.
- A value outside the allowed range gives `NULL`, not an error: `asin(2)` is `NULL`.
- Text is an error: `sin('a')`. Use `CAST` for text that holds a number.
- They return `DOUBLE`. Results like `sin(pi())` are a tiny number instead of exactly `0`: use `round(x, 10)` to clean them.
**Example: Angles in degrees and radians, with sine and cosine** (sample data: sample)
```sql
SELECT deg, round(radians(deg), 4) AS rad, round(sin(radians(deg)), 4) AS sin, round(cos(radians(deg)), 4) AS cos
FROM (SELECT 0 AS deg UNION ALL SELECT 30 UNION ALL SELECT 45 UNION ALL SELECT 90 UNION ALL SELECT 180) t
ORDER BY deg;
```
Result:
| deg (LONG) | rad (DOUBLE) | sin (DOUBLE) | cos (DOUBLE) |
|---|---|---|---|
| 0 | 0 | 0 | 1 |
| 30 | 0.5236 | 0.5 | 0.866 |
| 45 | 0.7854 | 0.7071 | 0.7071 |
| 90 | 1.5708 | 1 | 0 |
| 180 | 3.1416 | 0 | -1 |
(5 rows)
## sin
Syntax:
```sql
sin(x)
```
The **sine** of the angle `x` (in radians). As the angle goes round the circle, the sine goes smoothly up and down between `-1` and `1`, like a wave. Use it to make a cycle: `sin(2 × π × day / 8)` repeats every 8 days.
| Argument | Type | Meaning |
|---|---|---|
| `x` | any number | an angle in radians |
- **Returns:** `DOUBLE` from `-1` to `1`.
- **NULL:** `NULL` in, `NULL` out.
**Example** (sample data: sample)
```sql
SELECT sin(0) AS a, sin(pi() / 2) AS b, round(sin(radians(30)), 4) AS c, round(sin(pi()), 10) AS d;
```
Result:
| a (DOUBLE) | b (DOUBLE) | c (DOUBLE) | d (DOUBLE) |
|---|---|---|---|
| 0 | 1 | 0.5 | 0 |
(1 row)
**Example: An 8-day wave next to CITY's close** (sample data: sample)
```sql
SELECT time, close, round(sin(2 * pi() * row_number() / 8), 3) AS wave
FROM ochl_day
WHERE symbol = 'CITY' AND time >= '2026-09-02'
ORDER BY time;
```
Result:
| time (TIMESTAMP) | close (DOUBLE) | wave (DOUBLE) |
|---|---|---|
| 2026-09-02T00:00:00.000Z | 496.4 | 0.707 |
| 2026-09-03T00:00:00.000Z | 497.9 | 1 |
| 2026-09-06T00:00:00.000Z | 499 | 0.707 |
| 2026-09-07T00:00:00.000Z | 498.7 | 0 |
| 2026-09-08T00:00:00.000Z | 497.5 | -0.707 |
| 2026-09-09T00:00:00.000Z | 504.6 | -1 |
| 2026-09-10T00:00:00.000Z | 504.9 | -0.707 |
(7 rows)
## cos
Syntax:
```sql
cos(x)
```
The **cosine** of the angle `x` (in radians): the same wave as `sin`, a quarter circle earlier. `cos(0)` is `1`.
| Argument | Type | Meaning |
|---|---|---|
| `x` | any number | an angle in radians |
- **Returns:** `DOUBLE` from `-1` to `1`.
- **NULL:** `NULL` in, `NULL` out.
- **Notes:** `sin` and `cos` together put a month on a circle, so December (12) and January (1) come out close to each other. This is useful for **seasonality** (patterns that repeat every year) in reports and models.
**Example** (sample data: sample)
```sql
SELECT cos(0) AS a, round(cos(pi() / 2), 10) AS b, cos(pi()) AS c, round(cos(radians(60)), 4) AS d;
```
Result:
| a (DOUBLE) | b (DOUBLE) | c (DOUBLE) | d (DOUBLE) |
|---|---|---|---|
| 1 | 0 | -1 | 0.5 |
(1 row)
**Example: Months on a circle: December is next to January, July is far away** (sample data: sample)
```sql
SELECT m AS month,
round(sin(2 * pi() * (m - 1) / 12), 3) AS month_sin,
round(cos(2 * pi() * (m - 1) / 12), 3) AS month_cos
FROM (SELECT 1 AS m UNION ALL SELECT 4 UNION ALL SELECT 7 UNION ALL SELECT 12) t
ORDER BY m;
```
Result:
| month (LONG) | month_sin (DOUBLE) | month_cos (DOUBLE) |
|---|---|---|
| 1 | 0 | 1 |
| 4 | 1 | 0 |
| 7 | 0 | -1 |
| 12 | -0.5 | 0.866 |
(4 rows)
## tan
Syntax:
```sql
tan(x)
```
The **tangent** of the angle `x` (in radians): `sin(x) / cos(x)`. It is the **slope** of a line with that angle: how much it goes up for one step to the right. `tan(radians(45))` is `1`.
| Argument | Type | Meaning |
|---|---|---|
| `x` | any number | an angle in radians |
- **Returns:** `DOUBLE`.
- **NULL:** `NULL` in, `NULL` out.
- **Notes:** near 90° the tangent becomes very big.
**Example: Rise per step for a line at 10, 30, 45 and 60 degrees** (sample data: sample)
```sql
SELECT deg, round(tan(radians(deg)), 4) AS rise_per_step
FROM (SELECT 10 AS deg UNION ALL SELECT 30 UNION ALL SELECT 45 UNION ALL SELECT 60) t
ORDER BY deg;
```
Result:
| deg (LONG) | rise_per_step (DOUBLE) |
|---|---|
| 10 | 0.1763 |
| 30 | 0.5774 |
| 45 | 1 |
| 60 | 1.7321 |
(4 rows)
## cot
Syntax:
```sql
cot(x)
```
The **cotangent** of the angle `x` (in radians): `1 / tan(x)`, or `cos(x) / sin(x)`.
| Argument | Type | Meaning |
|---|---|---|
| `x` | any number | an angle in radians |
- **Returns:** `DOUBLE`.
- **NULL:** `NULL` in, `NULL` out. `cot(0)` is `NULL` (it would be a division by zero).
**Example** (sample data: sample)
```sql
SELECT round(cot(radians(45)), 4) AS a, round(cot(radians(60)), 4) AS b, round(1 / tan(radians(60)), 4) AS same, cot(0) AS zero;
```
Result:
| a (DOUBLE) | b (DOUBLE) | same (DOUBLE) | zero (STRING) |
|---|---|---|---|
| 1 | 0.5774 | 0.5774 | NULL |
(1 row)
## asin
Syntax:
```sql
asin(x)
```
The **arc sine**: the angle whose sine is `x`. It undoes `sin`. `asin(1)` is π/2 (90°).
| Argument | Type | Meaning |
|---|---|---|
| `x` | number from `-1` to `1` | a sine value |
- **Returns:** `DOUBLE`, an angle in radians from -π/2 to π/2.
- **NULL:** `NULL` in, `NULL` out. `x` below `-1` or above `1` gives `NULL`.
**Example** (sample data: sample)
```sql
SELECT asin(1) AS a, degrees(asin(0.5)) AS b_degrees, degrees(asin(-1)) AS c_degrees, asin(2) AS out_of_range;
```
Result:
| a (DOUBLE) | b_degrees (DOUBLE) | c_degrees (DOUBLE) | out_of_range (STRING) |
|---|---|---|---|
| 1.5707963267949 | 30 | -90 | NULL |
(1 row)
## acos
Syntax:
```sql
acos(x)
```
The **arc cosine**: the angle whose cosine is `x`. It undoes `cos`. `acos(1)` is `0`, `acos(-1)` is π (180°).
| Argument | Type | Meaning |
|---|---|---|
| `x` | number from `-1` to `1` | a cosine value |
- **Returns:** `DOUBLE`, an angle in radians from 0 to π.
- **NULL:** `NULL` in, `NULL` out. `x` below `-1` or above `1` gives `NULL`.
**Example** (sample data: sample)
```sql
SELECT acos(1) AS a, degrees(acos(0.5)) AS b_degrees, degrees(acos(-1)) AS c_degrees, acos(-2) AS out_of_range;
```
Result:
| a (DOUBLE) | b_degrees (DOUBLE) | c_degrees (DOUBLE) | out_of_range (STRING) |
|---|---|---|---|
| 0 | 60 | 180 | NULL |
(1 row)
## atan
Syntax:
```sql
atan(x)
```
The **arc tangent**: the angle whose tangent is `x`. It undoes `tan`, and turns a **slope** into an angle. `degrees(atan(1))` is `45`.
| Argument | Type | Meaning |
|---|---|---|
| `x` | any number | a tangent value (a slope) |
- **Returns:** `DOUBLE`, an angle in radians between -π/2 and π/2 (-90° and 90°).
- **NULL:** `NULL` in, `NULL` out.
- **Notes:** a chart angle depends on the scale of the chart. Measure the slope in **percent per candle**: then a rise of 1% per day is 45°.
**Example** (sample data: sample)
```sql
SELECT atan(0) AS a, degrees(atan(1)) AS b_degrees, degrees(atan(-1)) AS c_degrees, round(degrees(atan(1000000)), 3) AS almost_90;
```
Result:
| a (DOUBLE) | b_degrees (DOUBLE) | c_degrees (DOUBLE) | almost_90 (DOUBLE) |
|---|---|---|---|
| 0 | 45 | -45 | 90 |
(1 row)
**Example: Trend angle of VOLT: the rise over 4 days, in % per day, as an angle** (sample data: sample)
```sql
SELECT time, close, pct_per_day, round(degrees(atan(pct_per_day)), 1) AS angle_degrees
FROM (SELECT time, close, round((close / lag(close, 4) - 1) * 100 / 4, 3) AS pct_per_day
FROM ochl_day
WHERE symbol = 'VOLT' AND time >= '2026-08-23') t
WHERE time >= '2026-09-06'
ORDER BY time;
```
Result:
| time (TIMESTAMP) | close (DOUBLE) | pct_per_day (DOUBLE) | angle_degrees (DOUBLE) |
|---|---|---|---|
| 2026-09-06T00:00:00.000Z | 180.1 | 1.086 | 47.4 |
| 2026-09-07T00:00:00.000Z | 176.9 | 1.169 | 49.5 |
| 2026-09-08T00:00:00.000Z | 182.4 | 1.589 | 57.8 |
| 2026-09-09T00:00:00.000Z | 187.3 | 1.605 | 58.1 |
| 2026-09-10T00:00:00.000Z | 191.2 | 1.541 | 57 |
(5 rows)
## atan2
Syntax:
```sql
atan2(y, x)
```
The angle of the point (`x`, `y`) as seen from (0, 0). Unlike `atan(y / x)`, it knows which quarter of the circle the point is in, and it works when `x` is `0`. Note the order: `y` comes first.
| Argument | Type | Meaning |
|---|---|---|
| `y` | any number | the up-down position |
| `x` | any number | the left-right position |
- **Returns:** `DOUBLE`, an angle in radians from -π to π (-180° to 180°).
- **NULL:** `NULL` when an argument is `NULL`. `atan2(0, 0)` is `0`.
**Example: The angle of four points, one in each quarter** (sample data: sample)
```sql
SELECT x, y, round(degrees(atan2(y, x)), 1) AS angle_degrees, round(degrees(atan(y / x)), 1) AS atan_of_ratio
FROM (SELECT 1 AS x, 1 AS y UNION ALL SELECT -1, 1 UNION ALL SELECT -1, -1 UNION ALL SELECT 1, -1) t;
```
Result:
| x (LONG) | y (LONG) | angle_degrees (DOUBLE) | atan_of_ratio (DOUBLE) |
|---|---|---|---|
| 1 | 1 | 45 | 45 |
| -1 | 1 | 135 | -45 |
| -1 | -1 | -135 | 45 |
| 1 | -1 | -45 | -45 |
(4 rows)
## sinh, cosh, tanh
Syntax:
```sql
sinh(x)
cosh(x)
tanh(x)
```
The **hyperbolic** sine, cosine and tangent. They are made from `exp`: `sinh(x) = (e^x - e^-x) / 2`, `cosh(x) = (e^x + e^-x) / 2`, `tanh(x) = sinh(x) / cosh(x)`. The most useful one for data is `tanh`: it **squashes** any number into the range `-1` to `1`. Small values stay almost the same; very big values come close to `1` (or `-1`).
| Argument | Type | Meaning |
|---|---|---|
| `x` | any number | the value |
- **Returns:** `DOUBLE`. `tanh` is from `-1` to `1`; `cosh` is `1` or more.
- **NULL:** `NULL` in, `NULL` out. A result too big for a `DOUBLE` (like `sinh(1000)`) is `NULL`.
**Example** (sample data: sample)
```sql
SELECT sinh(0) AS sinh_0, round(sinh(1), 4) AS sinh_1, cosh(0) AS cosh_0, round(tanh(1), 4) AS tanh_1, round(tanh(5), 4) AS tanh_5, round(tanh(-5), 4) AS tanh_minus_5, sinh(1000) AS too_big;
```
Result:
| sinh_0 (DOUBLE) | sinh_1 (DOUBLE) | cosh_0 (DOUBLE) | tanh_1 (DOUBLE) | tanh_5 (DOUBLE) | tanh_minus_5 (DOUBLE) | too_big (STRING) |
|---|---|---|---|---|---|---|
| 0 | 1.1752 | 1 | 0.7616 | 0.9999 | -0.9999 | NULL |
(1 row)
**Example: A signal from -1 to 1: tanh of the daily % change** (sample data: sample)
```sql
SELECT time, symbol, round(chg, 2) AS change_pct, round(tanh(chg), 3) AS signal
FROM (SELECT time, symbol, pct_change(close) OVER (PARTITION BY symbol ORDER BY time) AS chg
FROM ochl_day
WHERE time >= '2026-09-06') t
WHERE time IN '2026-09-09'
ORDER BY symbol;
```
Result:
| time (TIMESTAMP) | symbol (SYMBOL) | change_pct (DOUBLE) | signal (DOUBLE) |
|---|---|---|---|
| 2026-09-09T00:00:00.000Z | CITY | 1.43 | 0.891 |
| 2026-09-09T00:00:00.000Z | COAST | 0.77 | 0.646 |
| 2026-09-09T00:00:00.000Z | VOLT | 2.69 | 0.991 |
(3 rows)
## asinh, acosh, atanh
Syntax:
```sql
asinh(x)
acosh(x)
atanh(x)
```
The inverse hyperbolic functions: they undo `sinh`, `cosh` and `tanh`.
| Function | Allowed `x` | Use |
|---|---|---|
| `asinh(x)` | any number | like a logarithm that also works for `0` and negative numbers: good to shrink big profits and losses for a chart |
| `acosh(x)` | `1` or more | undoes `cosh` |
| `atanh(x)` | more than `-1` and less than `1` | undoes `tanh`; it is the **Fisher transform** that traders use to make turning points of an oscillator sharper |
- **Returns:** `DOUBLE`.
- **NULL:** `NULL` in, `NULL` out. A value outside the allowed range gives `NULL`: `acosh(0.5)`, `atanh(1)`.
**Example** (sample data: sample)
```sql
SELECT round(asinh(1), 4) AS asinh_1, acosh(1) AS acosh_1, round(atanh(0.5), 4) AS atanh_half, round(atanh(tanh(0.3)), 4) AS back_to_0_3, acosh(0.5) AS out_of_range, atanh(1) AS atanh_1;
```
Result:
| asinh_1 (DOUBLE) | acosh_1 (DOUBLE) | atanh_half (DOUBLE) | back_to_0_3 (DOUBLE) | out_of_range (STRING) | atanh_1 (STRING) |
|---|---|---|---|---|---|
| 0.8814 | 0 | 0.5493 | 0.3 | NULL | NULL |
(1 row)
**Example: Shrink profits and losses with asinh (works for 0 and minus)** (sample data: sample)
```sql
SELECT pnl, round(asinh(pnl), 2) AS scaled
FROM (SELECT -100000 AS pnl UNION ALL SELECT -500 UNION ALL SELECT 0 UNION ALL SELECT 500 UNION ALL SELECT 100000) t
ORDER BY pnl;
```
Result:
| pnl (LONG) | scaled (DOUBLE) |
|---|---|
| -100000 | -12.21 |
| -500 | -6.91 |
| 0 | 0 |
| 500 | 6.91 |
| 100000 | 12.21 |
(5 rows)
## normal_cdf
Syntax:
```sql
normal_cdf(x)
normal_cdf(x, mean, stddev)
```
Many values spread around their average like a **bell**: most values are near the average, few are far away. The **normal distribution** is this bell shape. It is described by two numbers: the **mean** (the middle) and the **standard deviation** (how wide the bell is; see [stddev](functions-statistics.md#stddev)).
`normal_cdf` gives the **chance** that a value is **at or below** `x`, as a number from 0 to 1. For example, if CITY's daily return has mean -0.04% and standard deviation 0.75%, `normal_cdf(-2, -0.04, 0.75)` is the chance of a day worse than -2%.
| Argument | Type | Meaning |
|---|---|---|
| `x` | any number | the value |
| `mean` | any number | the middle of the bell; default `0` |
| `stddev` | number, more than 0 | the width of the bell; default `1` |
- **Returns:** `DOUBLE` from 0 to 1 (`0.025` means 2.5%).
- **NULL:** `NULL` when an argument is `NULL`.
- **Notes:** `stddev` of 0 or less is an error. With the defaults, `x` is a **z-score** (how many standard deviations from the mean): `normal_cdf(1.96)` is 0.975. Careful: real prices have more big jumps than the bell says, so treat the result as a rough guide. Like Excel `NORM.DIST(x, mean, sd, TRUE)`.
**Example** (sample data: sample)
```sql
SELECT normal_cdf(0) AS at_mean, round(normal_cdf(1.96), 4) AS z_1_96, round(normal_cdf(-1), 4) AS z_minus_1, round(normal_cdf(110, 100, 10), 4) AS one_sd_above;
```
Result:
| at_mean (DOUBLE) | z_1_96 (DOUBLE) | z_minus_1 (DOUBLE) | one_sd_above (DOUBLE) |
|---|---|---|---|
| 0.5 | 0.975 | 0.1587 | 0.8413 |
(1 row)
**Example: Chance of a day worse than -2%, from each share's daily returns** (sample data: sample)
```sql
SELECT symbol, count(chg) AS days,
round(avg(chg), 3) AS mean_pct,
round(stddev(chg), 3) AS stddev_pct,
round(normal_cdf(-2, avg(chg), stddev(chg)) * 100, 1) AS chance_pct
FROM (SELECT symbol, pct_change(close) OVER (PARTITION BY symbol ORDER BY time) AS chg
FROM ochl_day
WHERE time >= '2026-08-23') t
GROUP BY symbol
ORDER BY symbol;
```
Result:
| symbol (SYMBOL) | days (LONG) | mean_pct (DOUBLE) | stddev_pct (DOUBLE) | chance_pct (DOUBLE) |
|---|---|---|---|---|
| CITY | 14 | -0.04 | 0.746 | 0.4 |
| COAST | 14 | -0.271 | 1.145 | 6.5 |
| VOLT | 14 | 0.409 | 1.885 | 10.1 |
(3 rows)
**Example: The standard deviation must be more than 0** (sample data: sample; shows an error)
```sql
SELECT normal_cdf(1, 0, 0);
```
Result:
Error: `line 1, column 8: normal_cdf: the standard deviation must be more than 0`
## normal_pdf
Syntax:
```sql
normal_pdf(x)
normal_pdf(x, mean, stddev)
```
The **height of the bell** at `x` (the "density"). It is highest at the mean and gets lower far from it. The height itself is not a chance; compare two heights to see which value is more usual.
| Argument | Type | Meaning |
|---|---|---|
| `x` | any number | the value |
| `mean` | any number | the middle of the bell; default `0` |
| `stddev` | number, more than 0 | the width of the bell; default `1` |
- **Returns:** `DOUBLE`, more than 0.
- **NULL:** `NULL` when an argument is `NULL`.
- **Notes:** `stddev` of 0 or less is an error. Like Excel `NORM.DIST(x, mean, sd, FALSE)`.
**Example: The bell is highest at the mean** (sample data: sample)
```sql
SELECT z, round(normal_pdf(z), 4) AS height, round(normal_pdf(z) / normal_pdf(0), 3) AS compared_to_mean
FROM (SELECT 0 AS z UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) t
ORDER BY z;
```
Result:
| z (LONG) | height (DOUBLE) | compared_to_mean (DOUBLE) |
|---|---|---|
| 0 | 0.3989 | 1 |
| 1 | 0.242 | 0.607 |
| 2 | 0.054 | 0.135 |
| 3 | 0.0044 | 0.011 |
(4 rows)
**Example** (sample data: sample)
```sql
SELECT round(normal_pdf(100, 100, 10), 5) AS at_mean, round(normal_pdf(120, 100, 10), 5) AS two_sd_away;
```
Result:
| at_mean (DOUBLE) | two_sd_away (DOUBLE) |
|---|---|
| 0.03989 | 0.0054 |
(1 row)
## normal_inv
Syntax:
```sql
normal_inv(p)
normal_inv(p, mean, stddev)
```
The opposite of `normal_cdf`: the value `x` that has a chance `p` of being at or below it. `normal_inv(0.975)` is about `1.96`. Use it to find a level that is crossed only a small part of the time, for example the daily return that is worse only 5% of the days (a simple **value at risk**; see also [value_at_risk](functions-returns-risk.md#value_at_risk)).
| Argument | Type | Meaning |
|---|---|---|
| `p` | number, more than 0 and less than 1 | the chance |
| `mean` | any number | the middle of the bell; default `0` |
| `stddev` | number, more than 0 | the width of the bell; default `1` |
- **Returns:** `DOUBLE`.
- **NULL:** `NULL` when an argument is `NULL`.
- **Notes:** `p` of 0 or 1 or outside that range is an error, and so is a `stddev` of 0 or less. Like Excel `NORM.INV(p, mean, sd)`.
**Example: z-scores for 90%, 95% and 99% confidence** (sample data: sample)
```sql
SELECT round(normal_inv(0.95), 3) AS z_90_two_sided, round(normal_inv(0.975), 3) AS z_95_two_sided, round(normal_inv(0.995), 3) AS z_99_two_sided, normal_inv(0.5, 100, 10) AS middle;
```
Result:
| z_90_two_sided (DOUBLE) | z_95_two_sided (DOUBLE) | z_99_two_sided (DOUBLE) | middle (DOUBLE) |
|---|---|---|---|
| 1.645 | 1.96 | 2.576 | 100 |
(1 row)
**Example: The daily return that is worse only 5% of the days** (sample data: sample)
```sql
SELECT symbol, round(avg(chg), 3) AS mean_pct, round(stddev(chg), 3) AS stddev_pct,
round(normal_inv(0.05, avg(chg), stddev(chg)), 2) AS worst_5pct_day
FROM (SELECT symbol, pct_change(close) OVER (PARTITION BY symbol ORDER BY time) AS chg
FROM ochl_day
WHERE time >= '2026-08-23') t
GROUP BY symbol
ORDER BY symbol;
```
Result:
| symbol (SYMBOL) | mean_pct (DOUBLE) | stddev_pct (DOUBLE) | worst_5pct_day (DOUBLE) |
|---|---|---|---|
| CITY | -0.04 | 0.746 | -1.27 |
| COAST | -0.271 | 1.145 | -2.15 |
| VOLT | 0.409 | 1.885 | -2.69 |
(3 rows)
**Example: p must be more than 0 and less than 1** (sample data: sample; shows an error)
```sql
SELECT normal_inv(1);
```
Result:
Error: `line 1, column 8: normal_inv: the probability must be more than 0 and less than 1`