diff options
| -rw-r--r-- | CHANGES.md | 1 | ||||
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | api/api.md | 1643 | ||||
| -rw-r--r-- | api/builtins.md | 4 | ||||
| -rw-r--r-- | api/builtins.yaml | 2 | ||||
| -rw-r--r-- | api/floats.md (renamed from api/nums.md) | 402 | ||||
| -rw-r--r-- | api/floats.yaml (renamed from api/nums.yaml) | 394 | ||||
| -rw-r--r-- | api/lists.md | 6 | ||||
| -rw-r--r-- | api/lists.yaml | 4 | ||||
| -rw-r--r-- | docs/functions.md | 2 | ||||
| -rw-r--r-- | docs/nums.md | 14 | ||||
| -rw-r--r-- | docs/optionals.md | 2 | ||||
| -rw-r--r-- | examples/learnxiny.tm | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.1_PI.3 (renamed from man/man3/tomo-Num.1_PI.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.2_PI.3 (renamed from man/man3/tomo-Num.2_PI.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.2_SQRTPI.3 (renamed from man/man3/tomo-Num.2_SQRTPI.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.3 (renamed from man/man3/tomo-Num.3) | 260 | ||||
| -rw-r--r-- | man/man3/tomo-Float.E.3 (renamed from man/man3/tomo-Num.E.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.INF.3 (renamed from man/man3/tomo-Num.INF.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.LN10.3 (renamed from man/man3/tomo-Num.LN10.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.LN2.3 (renamed from man/man3/tomo-Num.LN2.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.LOG2E.3 (renamed from man/man3/tomo-Num.LOG2E.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.PI.3 (renamed from man/man3/tomo-Num.PI.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.PI_2.3 (renamed from man/man3/tomo-Num.PI_2.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.PI_4.3 (renamed from man/man3/tomo-Num.PI_4.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.SQRT1_2.3 (renamed from man/man3/tomo-Num.SQRT1_2.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.SQRT2.3 (renamed from man/man3/tomo-Num.SQRT2.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.TAU.3 (renamed from man/man3/tomo-Num.TAU.3) | 8 | ||||
| -rw-r--r-- | man/man3/tomo-Float.abs.3 (renamed from man/man3/tomo-Num.abs.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.acos.3 (renamed from man/man3/tomo-Num.acos.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.acosh.3 (renamed from man/man3/tomo-Num.acosh.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.asin.3 (renamed from man/man3/tomo-Num.asin.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.asinh.3 (renamed from man/man3/tomo-Num.asinh.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.atan.3 (renamed from man/man3/tomo-Num.atan.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.atan2.3 (renamed from man/man3/tomo-Num.atan2.3) | 14 | ||||
| -rw-r--r-- | man/man3/tomo-Float.atanh.3 (renamed from man/man3/tomo-Num.atanh.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.cbrt.3 (renamed from man/man3/tomo-Num.cbrt.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.ceil.3 (renamed from man/man3/tomo-Num.ceil.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.clamped.3 (renamed from man/man3/tomo-Num.clamped.3) | 14 | ||||
| -rw-r--r-- | man/man3/tomo-Float.copysign.3 (renamed from man/man3/tomo-Num.copysign.3) | 12 | ||||
| -rw-r--r-- | man/man3/tomo-Float.cos.3 (renamed from man/man3/tomo-Num.cos.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.cosh.3 (renamed from man/man3/tomo-Num.cosh.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.erf.3 (renamed from man/man3/tomo-Num.erf.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.erfc.3 (renamed from man/man3/tomo-Num.erfc.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.exp.3 (renamed from man/man3/tomo-Num.exp.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.exp2.3 (renamed from man/man3/tomo-Num.exp2.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.expm1.3 (renamed from man/man3/tomo-Num.expm1.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.fdim.3 (renamed from man/man3/tomo-Num.fdim.3) | 12 | ||||
| -rw-r--r-- | man/man3/tomo-Float.floor.3 (renamed from man/man3/tomo-Num.floor.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.hypot.3 (renamed from man/man3/tomo-Num.hypot.3) | 14 | ||||
| -rw-r--r-- | man/man3/tomo-Float.is_between.3 (renamed from man/man3/tomo-Num.is_between.3) | 16 | ||||
| -rw-r--r-- | man/man3/tomo-Float.isfinite.3 (renamed from man/man3/tomo-Num.isfinite.3) | 12 | ||||
| -rw-r--r-- | man/man3/tomo-Float.isinf.3 (renamed from man/man3/tomo-Num.isinf.3) | 12 | ||||
| -rw-r--r-- | man/man3/tomo-Float.j0.3 (renamed from man/man3/tomo-Num.j0.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.j1.3 (renamed from man/man3/tomo-Num.j1.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.log.3 (renamed from man/man3/tomo-Num.log.3) | 12 | ||||
| -rw-r--r-- | man/man3/tomo-Float.log10.3 (renamed from man/man3/tomo-Num.log10.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.log1p.3 (renamed from man/man3/tomo-Num.log1p.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.log2.3 (renamed from man/man3/tomo-Num.log2.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.logb.3 (renamed from man/man3/tomo-Num.logb.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.mix.3 (renamed from man/man3/tomo-Num.mix.3) | 14 | ||||
| -rw-r--r-- | man/man3/tomo-Float.near.3 (renamed from man/man3/tomo-Num.near.3) | 16 | ||||
| -rw-r--r-- | man/man3/tomo-Float.nextafter.3 (renamed from man/man3/tomo-Num.nextafter.3) | 12 | ||||
| -rw-r--r-- | man/man3/tomo-Float.parse.3 (renamed from man/man3/tomo-Num.parse.3) | 16 | ||||
| -rw-r--r-- | man/man3/tomo-Float.percent.3 (renamed from man/man3/tomo-Num.percent.3) | 12 | ||||
| -rw-r--r-- | man/man3/tomo-Float.rint.3 (renamed from man/man3/tomo-Num.rint.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.round.3 (renamed from man/man3/tomo-Num.round.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.significand.3 (renamed from man/man3/tomo-Num.significand.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.sin.3 (renamed from man/man3/tomo-Num.sin.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.sinh.3 (renamed from man/man3/tomo-Num.sinh.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.sqrt.3 (renamed from man/man3/tomo-Num.sqrt.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.tan.3 (renamed from man/man3/tomo-Num.tan.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.tanh.3 (renamed from man/man3/tomo-Num.tanh.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.tgamma.3 (renamed from man/man3/tomo-Num.tgamma.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.trunc.3 (renamed from man/man3/tomo-Num.trunc.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.with_precision.3 (renamed from man/man3/tomo-Num.with_precision.3) | 12 | ||||
| -rw-r--r-- | man/man3/tomo-Float.y0.3 (renamed from man/man3/tomo-Num.y0.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-Float.y1.3 (renamed from man/man3/tomo-Num.y1.3) | 10 | ||||
| -rw-r--r-- | man/man3/tomo-List.3 | 4 | ||||
| -rw-r--r-- | man/man3/tomo-List.sample.3 | 8 | ||||
| -rw-r--r-- | man/man3/tomo-USE_COLOR.3 | 2 | ||||
| -rw-r--r-- | man/man3/tomo-sleep.3 | 6 | ||||
| -rw-r--r-- | src/compile/assignments.c | 8 | ||||
| -rw-r--r-- | src/compile/binops.c | 27 | ||||
| -rw-r--r-- | src/compile/comparisons.c | 4 | ||||
| -rw-r--r-- | src/compile/expressions.c | 16 | ||||
| -rw-r--r-- | src/compile/functions.c | 20 | ||||
| -rw-r--r-- | src/compile/integers.c | 8 | ||||
| -rw-r--r-- | src/compile/lists.c | 4 | ||||
| -rw-r--r-- | src/compile/optionals.c | 6 | ||||
| -rw-r--r-- | src/compile/promotions.c | 7 | ||||
| -rw-r--r-- | src/compile/statements.c | 2 | ||||
| -rw-r--r-- | src/compile/text.c | 2 | ||||
| -rw-r--r-- | src/compile/types.c | 11 | ||||
| -rw-r--r-- | src/environment.c | 156 | ||||
| -rw-r--r-- | src/stdlib/README.md | 4 | ||||
| -rw-r--r-- | src/stdlib/bigint.c | 2 | ||||
| -rw-r--r-- | src/stdlib/bigint.h | 9 | ||||
| -rw-r--r-- | src/stdlib/cli.c | 23 | ||||
| -rw-r--r-- | src/stdlib/datatypes.h | 21 | ||||
| -rw-r--r-- | src/stdlib/float32.c | 4 | ||||
| -rw-r--r-- | src/stdlib/float64.c | 4 | ||||
| -rw-r--r-- | src/stdlib/floatX.c.h (renamed from src/stdlib/numX.c.h) | 108 | ||||
| -rw-r--r-- | src/stdlib/floatX.h | 103 | ||||
| -rw-r--r-- | src/stdlib/floats.h | 13 | ||||
| -rw-r--r-- | src/stdlib/intX.h | 11 | ||||
| -rw-r--r-- | src/stdlib/lists.c | 12 | ||||
| -rw-r--r-- | src/stdlib/num32.c | 4 | ||||
| -rw-r--r-- | src/stdlib/num64.c | 4 | ||||
| -rw-r--r-- | src/stdlib/nums.h | 13 | ||||
| -rw-r--r-- | src/stdlib/optionals.c | 6 | ||||
| -rw-r--r-- | src/stdlib/print.c | 6 | ||||
| -rw-r--r-- | src/stdlib/print.h | 2 | ||||
| -rw-r--r-- | src/stdlib/reals.c | 312 | ||||
| -rw-r--r-- | src/stdlib/reals.h | 29 | ||||
| -rw-r--r-- | src/stdlib/text.h | 6 | ||||
| -rw-r--r-- | src/stdlib/tomo.h | 3 | ||||
| -rw-r--r-- | src/typecheck.c | 18 | ||||
| -rw-r--r-- | src/types.c | 46 | ||||
| -rw-r--r-- | src/types.h | 10 | ||||
| -rw-r--r-- | test/_vectors.tm | 2 | ||||
| -rw-r--r-- | test/lists.tm | 4 | ||||
| -rw-r--r-- | test/minmax.tm | 4 | ||||
| -rw-r--r-- | test/nums.tm | 22 | ||||
| -rw-r--r-- | test/optionals.tm | 2 | ||||
| -rw-r--r-- | test/serialization.tm | 6 |
126 files changed, 2514 insertions, 2000 deletions
@@ -111,6 +111,7 @@ `$TOMO_PATH/share/tomo_TOMO_VERSION/installed/module_LIBRARY_VERSION` - Core libraries are no longer shipped with the compiler, they have moved to separate repositories. +- Renamed `Num` -> `Float64` and `Num32` -> `Float32` - Library installation has been cleaned up a bit. ### Type Changes @@ -182,8 +182,8 @@ config.mk: configure.sh # Integer implementations depend on the shared header: src/stdlib/int64.o src/stdlib/int32.o src/stdlib/int16.o src/stdlib/int8.o: src/stdlib/intX.c.h src/stdlib/intX.h -# Num implementations depend on the shared header: -src/stdlib/num32.o src/stdlib/num64.o: src/stdlib/numX.c.h +# Float implementations depend on the shared header: +src/stdlib/float32.o src/stdlib/float64.o: src/stdlib/floatX.c.h src/stdlib/floatX.h %: %.tm ./local-tomo -e $< @@ -187,14 +187,14 @@ setenv("FOOBAR", "xyz") ## sleep ```tomo -sleep : func(seconds: Num -> Void) +sleep : func(seconds: Float64 -> Void) ``` Pause execution for a given number of seconds. Argument | Type | Description | Default ---------|------|-------------|--------- -seconds | `Num` | How many seconds to sleep for. | - +seconds | `Float64` | How many seconds to sleep for. | - **Return:** Nothing. @@ -410,2126 +410,2125 @@ assert CString(",").join([CString("a"), CString("b")]) == CString("a,b") ``` -# Int -## Int.abs +# Float +## Float.1_PI ```tomo -Int.abs : func(x: Int -> Int) +Float.1_PI : Float ``` -Calculates the absolute value of an integer. +The constant $\frac{1}{\pi}$. -Argument | Type | Description | Default ----------|------|-------------|--------- -x | `Int` | The integer whose absolute value is to be calculated. | - +## Float.2_PI -**Return:** The absolute value of `x`. +```tomo +Float.2_PI : Float +``` +The constant $2 \times \pi$. -**Example:** -```tomo -assert (-10).abs() == 10 +## Float.2_SQRTPI +```tomo +Float.2_SQRTPI : Float ``` -## Int.choose + +The constant $2 \times \sqrt{\pi}$. + +## Float.E ```tomo -Int.choose : func(n: Int, k: Int -> Int) +Float.E : Float ``` -Computes the binomial coefficient of the given numbers (the equivalent of `n` choose `k` in combinatorics). This is equal to `n.factorial()/(k.factorial() * (n-k).factorial())`. +The base of the natural logarithm ($e$). -Argument | Type | Description | Default ----------|------|-------------|--------- -n | `Int` | The number of things to choose from. | - -k | `Int` | The number of things to be chosen. | - +## Float.INF -**Return:** The binomial coefficient, equivalent to the number of ways to uniquely choose `k` objects from among `n` objects, ignoring order. +```tomo +Float.INF : Float +``` +Positive infinity. -**Example:** -```tomo -assert (4).choose(2) == 6 +## Float.LN10 +```tomo +Float.LN10 : Float ``` -## Int.clamped + +The natural logarithm of 10. + +## Float.LN2 ```tomo -Int.clamped : func(x: Int, low: Int, high: Int -> Int) +Float.LN2 : Float ``` -Returns the given number clamped between two values so that it is within that range. +The natural logarithm of 2. -Argument | Type | Description | Default ----------|------|-------------|--------- -x | `Int` | The integer to clamp. | - -low | `Int` | The lowest value the result can take. | - -high | `Int` | The highest value the result can take. | - +## Float.LOG2E -**Return:** The first argument clamped between the other two arguments. +```tomo +Float.LOG2E : Float +``` +The base 2 logarithm of $e$ -**Example:** -```tomo -assert (2).clamped(5, 10) == 5 +## Float.PI +```tomo +Float.PI : Float ``` -## Int.factorial + +Pi ($\pi$). + +## Float.PI_2 ```tomo -Int.factorial : func(n: Int -> Text) +Float.PI_2 : Float ``` -Computes the factorial of an integer. +$\frac{\pi}{2}$ -Argument | Type | Description | Default ----------|------|-------------|--------- -n | `Int` | The integer to compute the factorial of. | - +## Float.PI_4 -**Return:** The factorial of the given integer. +```tomo +Float.PI_4 : Float +``` +$\frac{\pi}{4}$ + +## Float.SQRT1_2 -**Example:** ```tomo -assert (10).factorial() == 3628800 +Float.SQRT1_2 : Float +``` +$\sqrt{\frac{1}{2}}$ + +## Float.SQRT2 + +```tomo +Float.SQRT2 : Float ``` -## Int.get_bit + +$\sqrt{2}$ + +## Float.TAU ```tomo -Int.get_bit : func(i: Int, bit_index: Int -> Bool) +Float.TAU : Float ``` -In the binary representation of an integer, check whether a given bit index is set to 1 or not. +Tau ($2 \times \pi$) -For fixed-size integers, the bit index must be between 1 and the number of bits in that integer (i.e. 1-64 for `Int64`). For `Int`, the bit index must be between 1 and `Int64.max`. Values outside this range will produce a runtime error. +## Float.abs + +```tomo +Float.abs : func(n: Float -> Float) +``` + +Calculates the absolute value of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -i | `Int` | The integer whose bits are being inspected. | - -bit_index | `Int` | The index of the bit to check (1-indexed). | - +n | `Float` | The number whose absolute value is to be computed. | - -**Return:** Whether or not the given bit index is set to 1 in the binary representation of the integer. +**Return:** The absolute value of `n`. **Example:** ```tomo -assert (6).get_bit(1) == no -assert (6).get_bit(2) == yes -assert (6).get_bit(3) == yes -assert (6).get_bit(4) == no +assert (-3.5).abs() == 3.5 ``` -## Int.hex +## Float.acos ```tomo -Int.hex : func(i: Int, digits: Int = 0, uppercase: Bool = yes, prefix: Bool = yes -> Text) +Float.acos : func(x: Float -> Float) ``` -Converts an integer to its hexadecimal representation. +Computes the arc cosine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -i | `Int` | The integer to be converted. | - -digits | `Int` | The minimum number of digits in the output string. | `0` -uppercase | `Bool` | Whether to use uppercase letters for hexadecimal digits. | `yes` -prefix | `Bool` | Whether to include a "0x" prefix. | `yes` +x | `Float` | The number for which the arc cosine is to be calculated. | - -**Return:** The hexadecimal string representation of the integer. +**Return:** The arc cosine of `x` in radians. **Example:** ```tomo -assert (255).hex(digits=4, uppercase=yes, prefix=yes) == "0x00FF" +assert (0.0).acos() == 1.5708 ``` -## Int.is_between +## Float.acosh ```tomo -Int.is_between : func(x: Int, a: Int, b: Int -> Bool) +Float.acosh : func(x: Float -> Float) ``` -Determines if an integer is between two numbers (inclusive). +Computes the inverse hyperbolic cosine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Int` | The integer to be checked. | - -a | `Int` | One end of the range to check (inclusive). | - -b | `Int` | The other end of the range to check (inclusive). | - +x | `Float` | The number for which the inverse hyperbolic cosine is to be calculated. | - -**Return:** `yes` if `a <= x and x <= b` or `a >= x and x >= b`, otherwise `no` +**Return:** The inverse hyperbolic cosine of `x`. **Example:** ```tomo -assert (7).is_between(1, 10) == yes -assert (7).is_between(10, 1) == yes -assert (7).is_between(100, 200) == no -assert (7).is_between(1, 7) == yes +assert (1.0).acosh() == 0 ``` -## Int.is_prime +## Float.asin ```tomo -Int.is_prime : func(x: Int, reps: Int = 50 -> Bool) +Float.asin : func(x: Float -> Float) ``` -Determines if an integer is a prime number. - -This function is _probabilistic_. With the default arguments, the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See [the GNU MP docs](https://gmplib.org/manual/Number-Theoretic-Functions#index-mpz_005fprobab_005fprime_005fp) for more details. +Computes the arc sine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Int` | The integer to be checked. | - -reps | `Int` | The number of repetitions for primality tests. | `50` +x | `Float` | The number for which the arc sine is to be calculated. | - -**Return:** `yes` if `x` is a prime number, `no` otherwise. +**Return:** The arc sine of `x` in radians. **Example:** ```tomo -assert (7).is_prime() == yes -assert (6).is_prime() == no +assert (0.5).asin() == 0.5236 ``` -## Int.next_prime +## Float.asinh ```tomo -Int.next_prime : func(x: Int -> Int) +Float.asinh : func(x: Float -> Float) ``` -Finds the next prime number greater than the given integer. - -This function is _probabilistic_, but the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See [the GNU MP docs](https://gmplib.org/manual/Number-Theoretic-Functions#index-mpz_005fprobab_005fprime_005fp) for more details. +Computes the inverse hyperbolic sine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Int` | The integer after which to find the next prime. | - +x | `Float` | The number for which the inverse hyperbolic sine is to be calculated. | - -**Return:** The next prime number greater than `x`. +**Return:** The inverse hyperbolic sine of `x`. **Example:** ```tomo -assert (11).next_prime() == 13 +assert (0.0).asinh() == 0 ``` -## Int.octal +## Float.atan ```tomo -Int.octal : func(i: Int, digits: Int = 0, prefix: Bool = yes -> Text) +Float.atan : func(x: Float -> Float) ``` -Converts an integer to its octal representation. +Computes the arc tangent of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -i | `Int` | The integer to be converted. | - -digits | `Int` | The minimum number of digits in the output string. | `0` -prefix | `Bool` | Whether to include a "0o" prefix. | `yes` +x | `Float` | The number for which the arc tangent is to be calculated. | - -**Return:** The octal string representation of the integer. +**Return:** The arc tangent of `x` in radians. **Example:** ```tomo -assert (64).octal(digits=4, prefix=yes) == "0o0100" +assert (1.0).atan() == 0.7854 ``` -## Int.onward +## Float.atan2 ```tomo -Int.onward : func(first: Int, step: Int = 1 -> Text) +Float.atan2 : func(x: Float, y: Float -> Float) ``` -Return an iterator that counts infinitely from the starting integer (with an optional step size). +Computes the arc tangent of the quotient of two numbers. Argument | Type | Description | Default ---------|------|-------------|--------- -first | `Int` | The starting integer. | - -step | `Int` | The increment step size. | `1` +x | `Float` | The numerator. | - +y | `Float` | The denominator. | - -**Return:** An iterator function that counts onward from the starting integer. +**Return:** The arc tangent of `x/y` in radians. **Example:** ```tomo -nums : &[Int] = &[] -for i in (5).onward() -nums.insert(i) -stop if i == 10 -assert nums[] == [5, 6, 7, 8, 9, 10] +assert Float.atan2(1, 1) == 0.7854 ``` -## Int.parse +## Float.atanh ```tomo -Int.parse : func(text: Text, base: Int? = none, remainder: &Text? = none -> Int?) +Float.atanh : func(x: Float -> Float) ``` -Converts a text representation of an integer into an integer. +Computes the inverse hyperbolic tangent of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -text | `Text` | The text containing the integer. | - -base | `Int?` | The numeric base to use when parsing the integer. If unspecified, the integer's base will be inferred from the text prefix. After any "+" or "-" sign, if the text begins with "0x", the base will be assumed to be 16, "0o" will assume base 8, "0b" will assume base 2, otherwise the base will be assumed to be 10. | `none` -remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none` +x | `Float` | The number for which the inverse hyperbolic tangent is to be calculated. | - -**Return:** The integer represented by the text. If the given text contains a value outside of the representable range or if the entire text can't be parsed as an integer, `none` will be returned. +**Return:** The inverse hyperbolic tangent of `x`. **Example:** ```tomo -assert Int.parse("123") == 123 -assert Int.parse("0xFF") == 255 -assert Int.parse("123xyz") == none -remainder : Text -assert Int.parse("123xyz", &remainder) == 123 -assert remainder == "xyz" - -# Can't parse: -assert Int.parse("asdf") == none - -# Outside valid range: -assert Int8.parse("9999999") == none - -# Explicitly specifying base: -assert Int.parse("10", base=16) == 16 +assert (0.5).atanh() == 0.5493 ``` -## Int.prev_prime +## Float.cbrt ```tomo -Int.prev_prime : func(x: Int -> Int?) +Float.cbrt : func(x: Float -> Float) ``` -Finds the previous prime number less than the given integer. If there is no previous prime number (i.e. if a number less than `2` is provided), then the function will create a runtime error. - -This function is _probabilistic_, but the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See [the GNU MP docs](https://gmplib.org/manual/Number-Theoretic-Functions#index-mpz_005fprobab_005fprime_005fp) for more details. +Computes the cube root of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Int` | The integer before which to find the previous prime. | - +x | `Float` | The number for which the cube root is to be calculated. | - -**Return:** The previous prime number less than `x`, or `none` if `x` is less than 2. +**Return:** The cube root of `x`. **Example:** ```tomo -assert (11).prev_prime() == 7 +assert (27.0).cbrt() == 3 ``` -## Int.sqrt +## Float.ceil ```tomo -Int.sqrt : func(x: Int -> Int) +Float.ceil : func(x: Float -> Float) ``` -Calculates the nearest square root of an integer. +Rounds a number up to the nearest integer. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Int` | The integer whose square root is to be calculated. | - +x | `Float` | The number to be rounded up. | - -**Return:** The integer part of the square root of `x`. +**Return:** The smallest integer greater than or equal to `x`. **Example:** ```tomo -assert (16).sqrt() == 4 -assert (17).sqrt() == 4 +assert (3.2).ceil() == 4 ``` -## Int.to +## Float.clamped ```tomo -Int.to : func(first: Int, last: Int, step: Int? = none -> func(->Int?)) +Float.clamped : func(x: Float, low: Float, high: Float -> Float) ``` -Returns an iterator function that iterates over the range of numbers specified. +Returns the given number clamped between two values so that it is within that range. Argument | Type | Description | Default ---------|------|-------------|--------- -first | `Int` | The starting value of the range. | - -last | `Int` | The ending value of the range. | - -step | `Int?` | An optional step size to use. If unspecified or `none`, the step will be inferred to be `+1` if `last >= first`, otherwise `-1`. | `none` +x | `Float` | The number to clamp. | - +low | `Float` | The lowest value the result can take. | - +high | `Float` | The highest value the result can take. | - -**Return:** An iterator function that returns each integer in the given range (inclusive). +**Return:** The first argument clamped between the other two arguments. **Example:** ```tomo -iter := (2).to(5) -assert iter() == 2 -assert iter() == 3 -assert iter() == 4 -assert iter() == 5 -assert iter() == none - -assert [x for x in (2).to(5)] == [2, 3, 4, 5] -assert [x for x in (5).to(2)] == [5, 4, 3, 2] -assert [x for x in (2).to(5, step=2)] == [2, 4] +assert (2.5).clamped(5.5, 10.5) == 5.5 ``` - -# List -## List.binary_search +## Float.copysign ```tomo -List.binary_search : func(list: [T], by: func(x,y:&T->Int32) = T.compare -> Int) +Float.copysign : func(x: Float, y: Float -> Float) ``` -Performs a binary search on a sorted list. +Copies the sign of one number to another. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The sorted list to search. | - -by | `func(x,y:&T->Int32)` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` +x | `Float` | The number whose magnitude will be copied. | - +y | `Float` | The number whose sign will be copied. | - -**Return:** Assuming the input list is sorted according to the given comparison function, return the index where the given item would be inserted to maintain the sorted order. That is, if the item is found, return its index, otherwise return the place where it would be found if it were inserted and the list were sorted. +**Return:** A number with the magnitude of `x` and the sign of `y`. **Example:** ```tomo -assert [1, 3, 5, 7, 9].binary_search(5) == 3 -assert [1, 3, 5, 7, 9].binary_search(-999) == 1 -assert [1, 3, 5, 7, 9].binary_search(999) == 6 +assert (3.0).copysign(-1) == -3 ``` -## List.by +## Float.cos ```tomo -List.by : func(list: [T], step: Int -> [T]) +Float.cos : func(x: Float -> Float) ``` -Creates a new list with elements spaced by the specified step value. +Computes the cosine of a number (angle in radians). Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The original list. | - -step | `Int` | The step value for selecting elements. | - +x | `Float` | The angle in radians. | - -**Return:** A new list with every `step`-th element from the original list. +**Return:** The cosine of `x`. **Example:** ```tomo -assert [1, 2, 3, 4, 5, 6].by(2) == [1, 3, 5] +assert (0.0).cos() == 1 ``` -## List.clear +## Float.cosh ```tomo -List.clear : func(list: @[T] -> Void) +Float.cosh : func(x: Float -> Float) ``` -Clears all elements from the list. +Computes the hyperbolic cosine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the list to be cleared. | - +x | `Float` | The number for which the hyperbolic cosine is to be calculated. | - -**Return:** Nothing. +**Return:** The hyperbolic cosine of `x`. **Example:** ```tomo -my_list.clear() +assert (0.0).cosh() == 1 ``` -## List.counts +## Float.erf ```tomo -List.counts : func(list: [T] -> {T=Int}) +Float.erf : func(x: Float -> Float) ``` -Counts the occurrences of each element in the list. +Computes the error function of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list to count elements in. | - +x | `Float` | The number for which the error function is to be calculated. | - -**Return:** A table mapping each element to its count. +**Return:** The error function of `x`. **Example:** ```tomo -assert [10, 20, 30, 30, 30].counts() == {10=1, 20=1, 30=3} +assert (0.0).erf() == 0 ``` -## List.find +## Float.erfc ```tomo -List.find : func(list: [T], target: T -> Int?) +Float.erfc : func(x: Float -> Float) ``` -Finds the index of the first occurrence of an element (if any). +Computes the complementary error function of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list to search through. | - -target | `T` | The item to search for. | - +x | `Float` | The number for which the complementary error function is to be calculated. | - -**Return:** The index of the first occurrence or `none` if not found. +**Return:** The complementary error function of `x`. **Example:** ```tomo -assert [10, 20, 30, 40, 50].find(20) == 2 -assert [10, 20, 30, 40, 50].find(9999) == none +assert (0.0).erfc() == 1 ``` -## List.from +## Float.exp ```tomo -List.from : func(list: [T], first: Int -> [T]) +Float.exp : func(x: Float -> Float) ``` -Returns a slice of the list starting from a specified index. +Computes the exponential function $e^x$ for a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The original list. | - -first | `Int` | The index to start from. | - +x | `Float` | The exponent. | - -**Return:** A new list starting from the specified index. +**Return:** The value of $e^x$. **Example:** ```tomo -assert [10, 20, 30, 40, 50].from(3) == [30, 40, 50] +assert (1.0).exp() == 2.7183 ``` -## List.has +## Float.exp2 ```tomo -List.has : func(list: [T], target: T -> Bool) +Float.exp2 : func(x: Float -> Float) ``` -Checks if the list has an element. +Computes $2^x$ for a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list to check. | - -target | `T` | The element to check for. | - +x | `Float` | The exponent. | - -**Return:** `yes` if the list has the element, `no` otherwise. +**Return:** The value of $2^x$. **Example:** ```tomo -assert [10, 20, 30].has(20) == yes +assert (3.0).exp2() == 8 ``` -## List.heap_pop +## Float.expm1 ```tomo -List.heap_pop : func(list: @[T], by: func(x,y:&T->Int32) = T.compare -> T?) +Float.expm1 : func(x: Float -> Float) ``` -Removes and returns the top element of a heap or `none` if the list is empty. By default, this is the *minimum* value in the heap. +Computes $e^x - 1$ for a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the heap. | - -by | `func(x,y:&T->Int32)` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` +x | `Float` | The exponent. | - -**Return:** The removed top element of the heap or `none` if the list is empty. +**Return:** The value of $e^x - 1$. **Example:** ```tomo -my_heap := [30, 10, 20] -my_heap.heapify() -assert my_heap.heap_pop() == 10 +assert (1.0).expm1() == 1.7183 ``` -## List.heap_push +## Float.fdim ```tomo -List.heap_push : func(list: @[T], item: T, by = T.compare -> Void) +Float.fdim : func(x: Float, y: Float -> Float) ``` -Adds an element to the heap and maintains the heap property. By default, this is a *minimum* heap. +Computes the positive difference between two numbers. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the heap. | - -item | `T` | The item to be added. | - -by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` +x | `Float` | The first number. | - +y | `Float` | The second number. | - -**Return:** Nothing. +**Return:** The positive difference $\max(0, x - y)$. **Example:** ```tomo -my_heap.heap_push(10) +fd + +assert (5.0).fdim(3) == 2 ``` -## List.heapify +## Float.floor ```tomo -List.heapify : func(list: @[T], by: func(x,y:&T->Int32) = T.compare -> Void) +Float.floor : func(x: Float -> Float) ``` -Converts a list into a heap. +Rounds a number down to the nearest integer. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the list to be heapified. | - -by | `func(x,y:&T->Int32)` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` +x | `Float` | The number to be rounded down. | - -**Return:** Nothing. +**Return:** The largest integer less than or equal to `x`. **Example:** ```tomo -my_heap := [30, 10, 20] -my_heap.heapify() +assert (3.7).floor() == 3 ``` -## List.insert +## Float.hypot ```tomo -List.insert : func(list: @[T], item: T, at: Int = 0 -> Void) +Float.hypot : func(x: Float, y: Float -> Float) ``` -Inserts an element at a specified position in the list. - -Since indices are 1-indexed and negative indices mean "starting from the back", an index of `0` means "after the last item". +Computes the Euclidean norm, $\sqrt{x^2 + y^2}$, of two numbers. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the list. | - -item | `T` | The item to be inserted. | - -at | `Int` | The index at which to insert the item. | `0` +x | `Float` | The first number. | - +y | `Float` | The second number. | - -**Return:** Nothing. +**Return:** The Euclidean norm of `x` and `y`. **Example:** ```tomo -list := [10, 20] -list.insert(30) -assert list == [10, 20, 30] - -list.insert(999, at=2) -assert list == [10, 999, 20, 30] +assert Float.hypot(3, 4) == 5 ``` -## List.insert_all +## Float.is_between ```tomo -List.insert_all : func(list: @[T], items: [T], at: Int = 0 -> Void) +Float.is_between : func(x: Float, low: Float, high: Float -> Bool) ``` -Inserts a list of items at a specified position in the list. - -Since indices are 1-indexed and negative indices mean "starting from the back", an index of `0` means "after the last item". +Determines if a number is between two numbers (inclusive). Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the list. | - -items | `[T]` | The items to be inserted. | - -at | `Int` | The index at which to insert the item. | `0` +x | `Float` | The integer to be checked. | - +low | `Float` | The lower bound to check (inclusive). | - +high | `Float` | The upper bound to check (inclusive). | - -**Return:** Nothing. +**Return:** `yes` if `low <= x and x <= high`, otherwise `no` **Example:** ```tomo -list := [10, 20] -list.insert_all([30, 40]) -assert list == [10, 20, 30, 40] - -list.insert_all([99, 100], at=2) -assert list == [10, 99, 100, 20, 30, 40] +assert (7.5).is_between(1, 10) == yes +assert (7.5).is_between(100, 200) == no +assert (7.5).is_between(1, 7.5) == yes ``` -## List.pop +## Float.isfinite ```tomo -List.pop : func(list: &[T], index: Int = -1 -> T?) +Float.isfinite : func(n: Float -> Bool) ``` -Removes and returns an item from the list. If the given index is present in the list, the item at that index will be removed and the list will become one element shorter. - -Since negative indices are counted from the back, the default behavior is to pop the last value. +Checks if a number is finite. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `&[T]` | The list to remove an item from. | - -index | `Int` | The index from which to remove the item. | `-1` +n | `Float` | The number to be checked. | - -**Return:** `none` if the list is empty or the given index does not exist in the list, otherwise the item at the given index. +**Return:** `yes` if `n` is finite, `no` otherwise. **Example:** ```tomo -list := &[10, 20, 30, 40] - -assert list.pop() == 40 -assert list[] == [10, 20, 30] - -assert list.pop(index=2) == 20 -assert list[] == [10, 30] +assert (1.0).isfinite() == yes +assert Float.INF.isfinite() == no ``` -## List.random +## Float.isinf ```tomo -List.random : func(list: [T], random: func(min,max:Int64->Int64)? = none -> T) +Float.isinf : func(n: Float -> Bool) ``` -Selects a random element from the list. +Checks if a number is infinite. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list from which to select a random element. | - -random | `func(min,max:Int64->Int64)?` | If provided, this function will be used to get a random index in the list. Returned values must be between `min` and `max` (inclusive). (Used for deterministic pseudorandom number generation) | `none` +n | `Float` | The number to be checked. | - -**Return:** A random element from the list. +**Return:** `yes` if `n` is infinite, `no` otherwise. **Example:** ```tomo -assert [10, 20, 30].random() == 20 +assert Float.INF.isinf() == yes +assert (1.0).isinf() == no ``` -## List.remove_at +## Float.j0 ```tomo -List.remove_at : func(list: @[T], at: Int = -1, count: Int = 1 -> Void) +Float.j0 : func(x: Float -> Float) ``` -Removes elements from the list starting at a specified index. - -Since negative indices are counted from the back, the default behavior is to remove the last item. +Computes the Bessel function of the first kind of order 0. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the list. | - -at | `Int` | The index at which to start removing elements. | `-1` -count | `Int` | The number of elements to remove. | `1` +x | `Float` | The number for which the Bessel function is to be calculated. | - -**Return:** Nothing. +**Return:** The Bessel function of the first kind of order 0 of `x`. **Example:** ```tomo -list := [10, 20, 30, 40, 50] -list.remove_at(2) -assert list == [10, 30, 40, 50] - -list.remove_at(2, count=2) -assert list == [10, 50] +assert (0.0).j0() == 1 ``` -## List.remove_item +## Float.j1 ```tomo -List.remove_item : func(list: @[T], item: T, max_count: Int = -1 -> Void) +Float.j1 : func(x: Float -> Float) ``` -Removes all occurrences of a specified item from the list. - -A negative `max_count` means "remove all occurrences". +Computes the Bessel function of the first kind of order 1. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the list. | - -item | `T` | The item to be removed. | - -max_count | `Int` | The maximum number of occurrences to remove. | `-1` +x | `Float` | The number for which the Bessel function is to be calculated. | - -**Return:** Nothing. +**Return:** The Bessel function of the first kind of order 1 of `x`. **Example:** ```tomo -list := [10, 20, 10, 20, 30] -list.remove_item(10) -assert list == [20, 20, 30] - -list.remove_item(20, max_count=1) -assert list == [20, 30] +assert (0.0).j1() == 0 ``` -## List.reversed +## Float.log ```tomo -List.reversed : func(list: [T] -> [T]) +Float.log : func(x: Float -> Float) ``` -Returns a reversed slice of the list. +Computes the natural logarithm (base $e$) of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list to be reversed. | - +x | `Float` | The number for which the natural logarithm is to be calculated. | - -**Return:** A slice of the list with elements in reverse order. +**Return:** The natural logarithm of `x`. **Example:** ```tomo -assert [10, 20, 30].reversed() == [30, 20, 10] +assert Float.E.log() == 1 ``` -## List.sample +## Float.log10 ```tomo -List.sample : func(list: [T], count: Int, weights: [Num]? = none, random: func(->Num)? = none -> [T]) +Float.log10 : func(x: Float -> Float) ``` -Selects a sample of elements from the list, optionally with weighted probabilities. - -Errors will be raised if any of the following conditions occurs: - The given list has no elements and `count >= 1` - `count < 0` (negative count) - The number of weights provided doesn't match the length of the list. - Any weight in the weights list is negative, infinite, or `NaN` - The sum of the given weights is zero (zero probability for every element). +Computes the base-10 logarithm of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list to sample from. | - -count | `Int` | The number of elements to sample. | - -weights | `[Num]?` | The probability weights for each element in the list. These values do not need to add up to any particular number, they are relative weights. If no weights are given, elements will be sampled with uniform probability. | `none` -random | `func(->Num)?` | If provided, this function will be used to get random values for sampling the list. The provided function should return random numbers between `0.0` (inclusive) and `1.0` (exclusive). (Used for deterministic pseudorandom number generation) | `none` +x | `Float` | The number for which the base-10 logarithm is to be calculated. | - -**Return:** A list of sampled elements from the list. +**Return:** The base-10 logarithm of `x`. **Example:** ```tomo -assert [10, 20, 30].sample(2, weights=[90%, 5%, 5%]) == [10, 10] +assert (100.0).log10() == 2 ``` -## List.shuffle +## Float.log1p ```tomo -List.shuffle : func(list: @[T], random: func(min,max:Int64->Int64)? = none -> Void) +Float.log1p : func(x: Float -> Float) ``` -Shuffles the elements of the list in place. +Computes $\log(1 + x)$ for a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the list to be shuffled. | - -random | `func(min,max:Int64->Int64)?` | If provided, this function will be used to get a random index in the list. Returned values must be between `min` and `max` (inclusive). (Used for deterministic pseudorandom number generation) | `none` +x | `Float` | The number for which $\log(1 + x)$ is to be calculated. | - -**Return:** Nothing. +**Return:** The value of $\log(1 + x)$. **Example:** ```tomo -list.shuffle() +assert (1.0).log1p() == 0.6931 ``` -## List.shuffled +## Float.log2 ```tomo -List.shuffled : func(list: [T], random: func(min,max:Int64->Int64)? = none -> [T]) +Float.log2 : func(x: Float -> Float) ``` -Creates a new list with elements shuffled. +Computes the base-2 logarithm of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list to be shuffled. | - -random | `func(min,max:Int64->Int64)?` | If provided, this function will be used to get a random index in the list. Returned values must be between `min` and `max` (inclusive). (Used for deterministic pseudorandom number generation) | `none` +x | `Float` | The number for which the base-2 logarithm is to be calculated. | - -**Return:** A new list with shuffled elements. +**Return:** The base-2 logarithm of `x`. **Example:** ```tomo -assert [10, 20, 30, 40].shuffled() == [40, 10, 30, 20] +assert (8.0).log2() == 3 ``` -## List.slice +## Float.logb ```tomo -List.slice : func(list: [T], from: Int, to: Int -> [T]) +Float.logb : func(x: Float -> Float) ``` -Returns a slice of the list spanning the given indices (inclusive). +Computes the binary exponent (base-2 logarithm) of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The original list. | - -from | `Int` | The first index to include. | - -to | `Int` | The last index to include. | - +x | `Float` | The number for which the binary exponent is to be calculated. | - -**Return:** A new list spanning the given indices. Note: negative indices are counted from the back of the list, so `-1` refers to the last element, `-2` the second-to-last, and so on. +**Return:** The binary exponent of `x`. **Example:** ```tomo -assert [10, 20, 30, 40, 50].slice(2, 4) == [20, 30, 40] -assert [10, 20, 30, 40, 50].slice(-3, -2) == [30, 40] +assert (8.0).logb() == 3 ``` -## List.sort +## Float.mix ```tomo -List.sort : func(list: @[T], by = T.compare -> Void) +Float.mix : func(amount: Float, x: Float, y: Float -> Float) ``` -Sorts the elements of the list in place in ascending order (small to large). +Interpolates between two numbers based on a given amount. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `@[T]` | The mutable reference to the list to be sorted. | - -by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` +amount | `Float` | The interpolation factor (between `0` and `1`). | - +x | `Float` | The starting number. | - +y | `Float` | The ending number. | - -**Return:** Nothing. +**Return:** The interpolated number between `x` and `y` based on `amount`. **Example:** ```tomo -list := [40, 10, -30, 20] -list.sort() -assert list == [-30, 10, 20, 40] - -list.sort(func(a,b:&Int): a.abs() <> b.abs()) -assert list == [10, 20, -30, 40] +assert (0.5).mix(10, 20) == 15 +assert (0.25).mix(10, 20) == 12.5 ``` -## List.sorted +## Float.near ```tomo -List.sorted : func(list: [T], by = T.compare -> [T]) +Float.near : func(x: Float, y: Float, ratio: Float = 1e-9, min_epsilon: Float = 1e-9 -> Bool) ``` -Creates a new list with elements sorted. +Checks if two numbers are approximately equal within specified tolerances. If two numbers are within an absolute difference or the ratio between the two is small enough, they are considered near each other. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list to be sorted. | - -by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` +x | `Float` | The first number. | - +y | `Float` | The second number. | - +ratio | `Float` | The relative tolerance. Default is `1e-9`. | `1e-9` +min_epsilon | `Float` | The absolute tolerance. Default is `1e-9`. | `1e-9` -**Return:** A new list with sorted elements. +**Return:** `yes` if `x` and `y` are approximately equal within the specified tolerances, `no` otherwise. **Example:** ```tomo -assert [40, 10, -30, 20].sorted() == [-30, 10, 20, 40] -assert [40, 10, -30, 20].sorted( - func(a,b:&Int): a.abs() <> b.abs() -) == [10, 20, -30, 40] +assert (1.0).near(1.000000001) == yes +assert (100.0).near(110, ratio=0.1) == yes +assert (5.0).near(5.1, min_epsilon=0.1) == yes ``` -## List.to +## Float.nextafter ```tomo -List.to : func(list: [T], last: Int -> [T]) +Float.nextafter : func(x: Float, y: Float -> Float) ``` -Returns a slice of the list from the start of the original list up to a specified index (inclusive). +Computes the next representable value after a given number towards a specified direction. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The original list. | - -last | `Int` | The index up to which elements should be included. | - +x | `Float` | The starting number. | - +y | `Float` | The direction towards which to find the next representable value. | - -**Return:** A new list containing elements from the start up to the specified index. +**Return:** The next representable value after `x` in the direction of `y`. **Example:** ```tomo -assert [10, 20, 30, 40, 50].to(3) == [10, 20, 30] -assert [10, 20, 30, 40, 50].to(-2) == [10, 20, 30, 40] +assert (1.0).nextafter(1.1) == 1.0000000000000002 ``` -## List.unique +## Float.parse ```tomo -List.unique : func(list: [T] -> {T}) +Float.parse : func(text: Text, remainder: &Text? = none -> Float?) ``` -Returns a set of the unique elements of the list. +Converts a text representation of a number into a floating-point number. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list to process. | - +text | `Text` | The text containing the number. | - +remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none` -**Return:** A set of the unique elements from the list. +**Return:** The number represented by the text or `none` if the entire text can't be parsed as a number. **Example:** ```tomo -assert [10, 20, 10, 10, 30].unique() == {10, 20, 30} +assert Float.parse("3.14") == 3.14 +assert Float.parse("1e3") == 1000 +assert Float.parse("1.5junk") == none +remainder : Text +assert Float.parse("1.5junk", &remainder) == 1.5 +assert remainder == "junk" ``` -## List.where +## Float.percent ```tomo -List.where : func(list: [T], predicate: func(item:&T -> Bool) -> Int) +Float.percent : func(n: Float, precision: Float = 0.01 -> Text) ``` -Find the index of the first item that matches a predicate function (if any). +Convert a number into a percentage text with a percent sign. Argument | Type | Description | Default ---------|------|-------------|--------- -list | `[T]` | The list to search through. | - -predicate | `func(item:&T -> Bool)` | A function that returns `yes` if the item's index should be returned or `no` if it should not. | - +n | `Float` | The number to be converted to a percent. | - +precision | `Float` | Round the percentage to this precision level. | `0.01` -**Return:** Returns the index of the first item where the predicate is true or `none` if no item matches. +**Return:** A text representation of the number as a percentage with a percent sign. **Example:** ```tomo -assert [4, 5, 6].where(func(i:&Int): i.is_prime()) == 5 -assert [4, 6, 8].find(func(i:&Int): i.is_prime()) == none +assert (0.5).percent() == "50%" +assert (1./3.).percent(2) == "33.33%" +assert (1./3.).percent(2, precision=0.0001) == "33.3333%" +assert (1./3.).percent(2, precision=10.) == "30%" ``` - -# Num -## Num.1_PI +## Float.rint ```tomo -Num.1_PI : Num +Float.rint : func(x: Float -> Float) ``` -The constant $\frac{1}{\pi}$. - -## Num.2_PI +Rounds a number to the nearest integer, with ties rounded to the nearest even integer. -```tomo -Num.2_PI : Num -``` +Argument | Type | Description | Default +---------|------|-------------|--------- +x | `Float` | The number to be rounded. | - -The constant $2 \times \pi$. +**Return:** The nearest integer value of `x`. -## Num.2_SQRTPI +**Example:** ```tomo -Num.2_SQRTPI : Num -``` - -The constant $2 \times \sqrt{\pi}$. - -## Num.E +assert (3.5).rint() == 4 +assert (2.5).rint() == 2 -```tomo -Num.E : Num ``` - -The base of the natural logarithm ($e$). - -## Num.INF +## Float.round ```tomo -Num.INF : Num +Float.round : func(x: Float -> Float) ``` -Positive infinity. - -## Num.LN10 +Rounds a number to the nearest whole number integer. -```tomo -Num.LN10 : Num -``` +Argument | Type | Description | Default +---------|------|-------------|--------- +x | `Float` | The number to be rounded. | - -The natural logarithm of 10. +**Return:** The nearest integer value of `x`. -## Num.LN2 +**Example:** ```tomo -Num.LN2 : Num -``` - -The natural logarithm of 2. - -## Num.LOG2E +assert (2.3).round() == 2 +assert (2.7).round() == 3 -```tomo -Num.LOG2E : Num ``` - -The base 2 logarithm of $e$ - -## Num.PI +## Float.significand ```tomo -Num.PI : Num +Float.significand : func(x: Float -> Float) ``` -Pi ($\pi$). - -## Num.PI_2 +Extracts the significand (or mantissa) of a number. -```tomo -Num.PI_2 : Num -``` +Argument | Type | Description | Default +---------|------|-------------|--------- +x | `Float` | The number from which to extract the significand. | - -$\frac{\pi}{2}$ +**Return:** The significand of `x`. -## Num.PI_4 +**Example:** ```tomo -Num.PI_4 : Num -``` - -$\frac{\pi}{4}$ +assert (1234.567).significand() == 0.1234567 -## Num.SQRT1_2 +``` +## Float.sin ```tomo -Num.SQRT1_2 : Num +Float.sin : func(x: Float -> Float) ``` -$\sqrt{\frac{1}{2}}$ - -## Num.SQRT2 +Computes the sine of a number (angle in radians). -```tomo -Num.SQRT2 : Num -``` +Argument | Type | Description | Default +---------|------|-------------|--------- +x | `Float` | The angle in radians. | - -$\sqrt{2}$ +**Return:** The sine of `x`. -## Num.TAU +**Example:** ```tomo -Num.TAU : Num -``` - -Tau ($2 \times \pi$) +assert (0.0).sin() == 0 -## Num.abs +``` +## Float.sinh ```tomo -Num.abs : func(n: Num -> Num) +Float.sinh : func(x: Float -> Float) ``` -Calculates the absolute value of a number. +Computes the hyperbolic sine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number whose absolute value is to be computed. | - +x | `Float` | The number for which the hyperbolic sine is to be calculated. | - -**Return:** The absolute value of `n`. +**Return:** The hyperbolic sine of `x`. **Example:** ```tomo -assert (-3.5).abs() == 3.5 +assert (0.0).sinh() == 0 ``` -## Num.acos +## Float.sqrt ```tomo -Num.acos : func(x: Num -> Num) +Float.sqrt : func(x: Float -> Float) ``` -Computes the arc cosine of a number. +Computes the square root of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the arc cosine is to be calculated. | - +x | `Float` | The number for which the square root is to be calculated. | - -**Return:** The arc cosine of `x` in radians. +**Return:** The square root of `x`. **Example:** ```tomo -assert (0.0).acos() == 1.5708 +assert (16.0).sqrt() == 4 ``` -## Num.acosh +## Float.tan ```tomo -Num.acosh : func(x: Num -> Num) +Float.tan : func(x: Float -> Float) ``` -Computes the inverse hyperbolic cosine of a number. +Computes the tangent of a number (angle in radians). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the inverse hyperbolic cosine is to be calculated. | - +x | `Float` | The angle in radians. | - -**Return:** The inverse hyperbolic cosine of `x`. +**Return:** The tangent of `x`. **Example:** ```tomo -assert (1.0).acosh() == 0 +assert (0.0).tan() == 0 ``` -## Num.asin +## Float.tanh ```tomo -Num.asin : func(x: Num -> Num) +Float.tanh : func(x: Float -> Float) ``` -Computes the arc sine of a number. +Computes the hyperbolic tangent of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the arc sine is to be calculated. | - +x | `Float` | The number for which the hyperbolic tangent is to be calculated. | - -**Return:** The arc sine of `x` in radians. +**Return:** The hyperbolic tangent of `x`. **Example:** ```tomo -assert (0.5).asin() == 0.5236 +assert (0.0).tanh() == 0 ``` -## Num.asinh +## Float.tgamma ```tomo -Num.asinh : func(x: Num -> Num) +Float.tgamma : func(x: Float -> Float) ``` -Computes the inverse hyperbolic sine of a number. +Computes the gamma function of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the inverse hyperbolic sine is to be calculated. | - +x | `Float` | The number for which the gamma function is to be calculated. | - -**Return:** The inverse hyperbolic sine of `x`. +**Return:** The gamma function of `x`. **Example:** ```tomo -assert (0.0).asinh() == 0 +assert (1.0).tgamma() == 1 ``` -## Num.atan +## Float.trunc ```tomo -Num.atan : func(x: Num -> Num) +Float.trunc : func(x: Float -> Float) ``` -Computes the arc tangent of a number. +Truncates a number to the nearest integer towards zero. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the arc tangent is to be calculated. | - +x | `Float` | The number to be truncated. | - -**Return:** The arc tangent of `x` in radians. +**Return:** The integer part of `x` towards zero. **Example:** ```tomo -assert (1.0).atan() == 0.7854 +assert (3.7).trunc() == 3 +assert (-3.7).trunc() == -3 ``` -## Num.atan2 +## Float.with_precision ```tomo -Num.atan2 : func(x: Num, y: Num -> Num) +Float.with_precision : func(n: Float, precision: Float -> Float) ``` -Computes the arc tangent of the quotient of two numbers. +Round a number to the given precision level (specified as `10`, `.1`, `.001` etc). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The numerator. | - -y | `Num` | The denominator. | - +n | `Float` | The number to be rounded to a given precision. | - +precision | `Float` | The precision to which the number should be rounded. | - -**Return:** The arc tangent of `x/y` in radians. +**Return:** The number, rounded to the given precision level. **Example:** ```tomo -assert Num.atan2(1, 1) == 0.7854 +assert (0.1234567).with_precision(0.01) == 0.12 +assert (123456.).with_precision(100) == 123500 +assert (1234567.).with_precision(5) == 1234565 ``` -## Num.atanh +## Float.y0 ```tomo -Num.atanh : func(x: Num -> Num) +Float.y0 : func(x: Float -> Float) ``` -Computes the inverse hyperbolic tangent of a number. +Computes the Bessel function of the second kind of order 0. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the inverse hyperbolic tangent is to be calculated. | - +x | `Float` | The number for which the Bessel function is to be calculated. | - -**Return:** The inverse hyperbolic tangent of `x`. +**Return:** The Bessel function of the second kind of order 0 of `x`. **Example:** ```tomo -assert (0.5).atanh() == 0.5493 +assert (1.0).y0() == -0.7652 ``` -## Num.cbrt +## Float.y1 ```tomo -Num.cbrt : func(x: Num -> Num) +Float.y1 : func(x: Float -> Float) ``` -Computes the cube root of a number. +Computes the Bessel function of the second kind of order 1. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the cube root is to be calculated. | - +x | `Float` | The number for which the Bessel function is to be calculated. | - -**Return:** The cube root of `x`. +**Return:** The Bessel function of the second kind of order 1 of `x`. **Example:** ```tomo -assert (27.0).cbrt() == 3 +assert (1.0).y1() == 0.4401 ``` -## Num.ceil + +# Int +## Int.abs ```tomo -Num.ceil : func(x: Num -> Num) +Int.abs : func(x: Int -> Int) ``` -Rounds a number up to the nearest integer. +Calculates the absolute value of an integer. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be rounded up. | - +x | `Int` | The integer whose absolute value is to be calculated. | - -**Return:** The smallest integer greater than or equal to `x`. +**Return:** The absolute value of `x`. **Example:** ```tomo -assert (3.2).ceil() == 4 +assert (-10).abs() == 10 ``` -## Num.clamped +## Int.choose ```tomo -Num.clamped : func(x: Num, low: Num, high: Num -> Num) +Int.choose : func(n: Int, k: Int -> Int) ``` -Returns the given number clamped between two values so that it is within that range. +Computes the binomial coefficient of the given numbers (the equivalent of `n` choose `k` in combinatorics). This is equal to `n.factorial()/(k.factorial() * (n-k).factorial())`. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to clamp. | - -low | `Num` | The lowest value the result can take. | - -high | `Num` | The highest value the result can take. | - +n | `Int` | The number of things to choose from. | - +k | `Int` | The number of things to be chosen. | - -**Return:** The first argument clamped between the other two arguments. +**Return:** The binomial coefficient, equivalent to the number of ways to uniquely choose `k` objects from among `n` objects, ignoring order. **Example:** ```tomo -assert (2.5).clamped(5.5, 10.5) == 5.5 +assert (4).choose(2) == 6 ``` -## Num.copysign +## Int.clamped ```tomo -Num.copysign : func(x: Num, y: Num -> Num) +Int.clamped : func(x: Int, low: Int, high: Int -> Int) ``` -Copies the sign of one number to another. +Returns the given number clamped between two values so that it is within that range. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number whose magnitude will be copied. | - -y | `Num` | The number whose sign will be copied. | - +x | `Int` | The integer to clamp. | - +low | `Int` | The lowest value the result can take. | - +high | `Int` | The highest value the result can take. | - -**Return:** A number with the magnitude of `x` and the sign of `y`. +**Return:** The first argument clamped between the other two arguments. **Example:** ```tomo -assert (3.0).copysign(-1) == -3 +assert (2).clamped(5, 10) == 5 ``` -## Num.cos +## Int.factorial ```tomo -Num.cos : func(x: Num -> Num) +Int.factorial : func(n: Int -> Text) ``` -Computes the cosine of a number (angle in radians). +Computes the factorial of an integer. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The angle in radians. | - +n | `Int` | The integer to compute the factorial of. | - -**Return:** The cosine of `x`. +**Return:** The factorial of the given integer. **Example:** ```tomo -assert (0.0).cos() == 1 +assert (10).factorial() == 3628800 ``` -## Num.cosh +## Int.get_bit ```tomo -Num.cosh : func(x: Num -> Num) +Int.get_bit : func(i: Int, bit_index: Int -> Bool) ``` -Computes the hyperbolic cosine of a number. +In the binary representation of an integer, check whether a given bit index is set to 1 or not. + +For fixed-size integers, the bit index must be between 1 and the number of bits in that integer (i.e. 1-64 for `Int64`). For `Int`, the bit index must be between 1 and `Int64.max`. Values outside this range will produce a runtime error. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the hyperbolic cosine is to be calculated. | - +i | `Int` | The integer whose bits are being inspected. | - +bit_index | `Int` | The index of the bit to check (1-indexed). | - -**Return:** The hyperbolic cosine of `x`. +**Return:** Whether or not the given bit index is set to 1 in the binary representation of the integer. **Example:** ```tomo -assert (0.0).cosh() == 1 +assert (6).get_bit(1) == no +assert (6).get_bit(2) == yes +assert (6).get_bit(3) == yes +assert (6).get_bit(4) == no ``` -## Num.erf +## Int.hex ```tomo -Num.erf : func(x: Num -> Num) +Int.hex : func(i: Int, digits: Int = 0, uppercase: Bool = yes, prefix: Bool = yes -> Text) ``` -Computes the error function of a number. +Converts an integer to its hexadecimal representation. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the error function is to be calculated. | - +i | `Int` | The integer to be converted. | - +digits | `Int` | The minimum number of digits in the output string. | `0` +uppercase | `Bool` | Whether to use uppercase letters for hexadecimal digits. | `yes` +prefix | `Bool` | Whether to include a "0x" prefix. | `yes` -**Return:** The error function of `x`. +**Return:** The hexadecimal string representation of the integer. **Example:** ```tomo -assert (0.0).erf() == 0 +assert (255).hex(digits=4, uppercase=yes, prefix=yes) == "0x00FF" ``` -## Num.erfc +## Int.is_between ```tomo -Num.erfc : func(x: Num -> Num) +Int.is_between : func(x: Int, a: Int, b: Int -> Bool) ``` -Computes the complementary error function of a number. +Determines if an integer is between two numbers (inclusive). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the complementary error function is to be calculated. | - +x | `Int` | The integer to be checked. | - +a | `Int` | One end of the range to check (inclusive). | - +b | `Int` | The other end of the range to check (inclusive). | - -**Return:** The complementary error function of `x`. +**Return:** `yes` if `a <= x and x <= b` or `a >= x and x >= b`, otherwise `no` **Example:** ```tomo -assert (0.0).erfc() == 1 +assert (7).is_between(1, 10) == yes +assert (7).is_between(10, 1) == yes +assert (7).is_between(100, 200) == no +assert (7).is_between(1, 7) == yes ``` -## Num.exp +## Int.is_prime ```tomo -Num.exp : func(x: Num -> Num) +Int.is_prime : func(x: Int, reps: Int = 50 -> Bool) ``` -Computes the exponential function $e^x$ for a number. +Determines if an integer is a prime number. + +This function is _probabilistic_. With the default arguments, the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See [the GNU MP docs](https://gmplib.org/manual/Number-Theoretic-Functions#index-mpz_005fprobab_005fprime_005fp) for more details. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The exponent. | - +x | `Int` | The integer to be checked. | - +reps | `Int` | The number of repetitions for primality tests. | `50` -**Return:** The value of $e^x$. +**Return:** `yes` if `x` is a prime number, `no` otherwise. **Example:** ```tomo -assert (1.0).exp() == 2.7183 +assert (7).is_prime() == yes +assert (6).is_prime() == no ``` -## Num.exp2 +## Int.next_prime ```tomo -Num.exp2 : func(x: Num -> Num) +Int.next_prime : func(x: Int -> Int) ``` -Computes $2^x$ for a number. +Finds the next prime number greater than the given integer. + +This function is _probabilistic_, but the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See [the GNU MP docs](https://gmplib.org/manual/Number-Theoretic-Functions#index-mpz_005fprobab_005fprime_005fp) for more details. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The exponent. | - +x | `Int` | The integer after which to find the next prime. | - -**Return:** The value of $2^x$. +**Return:** The next prime number greater than `x`. **Example:** ```tomo -assert (3.0).exp2() == 8 +assert (11).next_prime() == 13 ``` -## Num.expm1 +## Int.octal ```tomo -Num.expm1 : func(x: Num -> Num) +Int.octal : func(i: Int, digits: Int = 0, prefix: Bool = yes -> Text) ``` -Computes $e^x - 1$ for a number. +Converts an integer to its octal representation. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The exponent. | - +i | `Int` | The integer to be converted. | - +digits | `Int` | The minimum number of digits in the output string. | `0` +prefix | `Bool` | Whether to include a "0o" prefix. | `yes` -**Return:** The value of $e^x - 1$. +**Return:** The octal string representation of the integer. **Example:** ```tomo -assert (1.0).expm1() == 1.7183 +assert (64).octal(digits=4, prefix=yes) == "0o0100" ``` -## Num.fdim +## Int.onward ```tomo -Num.fdim : func(x: Num, y: Num -> Num) +Int.onward : func(first: Int, step: Int = 1 -> Text) ``` -Computes the positive difference between two numbers. +Return an iterator that counts infinitely from the starting integer (with an optional step size). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The first number. | - -y | `Num` | The second number. | - +first | `Int` | The starting integer. | - +step | `Int` | The increment step size. | `1` -**Return:** The positive difference $\max(0, x - y)$. +**Return:** An iterator function that counts onward from the starting integer. **Example:** ```tomo -fd - -assert (5.0).fdim(3) == 2 +nums : &[Int] = &[] +for i in (5).onward() +nums.insert(i) +stop if i == 10 +assert nums[] == [5, 6, 7, 8, 9, 10] ``` -## Num.floor +## Int.parse ```tomo -Num.floor : func(x: Num -> Num) +Int.parse : func(text: Text, base: Int? = none, remainder: &Text? = none -> Int?) ``` -Rounds a number down to the nearest integer. +Converts a text representation of an integer into an integer. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be rounded down. | - +text | `Text` | The text containing the integer. | - +base | `Int?` | The numeric base to use when parsing the integer. If unspecified, the integer's base will be inferred from the text prefix. After any "+" or "-" sign, if the text begins with "0x", the base will be assumed to be 16, "0o" will assume base 8, "0b" will assume base 2, otherwise the base will be assumed to be 10. | `none` +remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none` -**Return:** The largest integer less than or equal to `x`. +**Return:** The integer represented by the text. If the given text contains a value outside of the representable range or if the entire text can't be parsed as an integer, `none` will be returned. **Example:** ```tomo -assert (3.7).floor() == 3 +assert Int.parse("123") == 123 +assert Int.parse("0xFF") == 255 +assert Int.parse("123xyz") == none +remainder : Text +assert Int.parse("123xyz", &remainder) == 123 +assert remainder == "xyz" + +# Can't parse: +assert Int.parse("asdf") == none + +# Outside valid range: +assert Int8.parse("9999999") == none + +# Explicitly specifying base: +assert Int.parse("10", base=16) == 16 ``` -## Num.hypot +## Int.prev_prime ```tomo -Num.hypot : func(x: Num, y: Num -> Num) +Int.prev_prime : func(x: Int -> Int?) ``` -Computes the Euclidean norm, $\sqrt{x^2 + y^2}$, of two numbers. +Finds the previous prime number less than the given integer. If there is no previous prime number (i.e. if a number less than `2` is provided), then the function will create a runtime error. + +This function is _probabilistic_, but the chances of getting an incorrect answer are astronomically small (on the order of 10^(-30)). See [the GNU MP docs](https://gmplib.org/manual/Number-Theoretic-Functions#index-mpz_005fprobab_005fprime_005fp) for more details. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The first number. | - -y | `Num` | The second number. | - +x | `Int` | The integer before which to find the previous prime. | - -**Return:** The Euclidean norm of `x` and `y`. +**Return:** The previous prime number less than `x`, or `none` if `x` is less than 2. **Example:** ```tomo -assert Num.hypot(3, 4) == 5 +assert (11).prev_prime() == 7 ``` -## Num.is_between +## Int.sqrt ```tomo -Num.is_between : func(x: Num, low: Num, high: Num -> Bool) +Int.sqrt : func(x: Int -> Int) ``` -Determines if a number is between two numbers (inclusive). +Calculates the nearest square root of an integer. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The integer to be checked. | - -low | `Num` | One end of the range to check (inclusive). | - -high | `Num` | The other end of the range to check (inclusive). | - +x | `Int` | The integer whose square root is to be calculated. | - -**Return:** `yes` if `a <= x and x <= b` or `b <= x and x <= a`, otherwise `no` +**Return:** The integer part of the square root of `x`. **Example:** ```tomo -assert (7.5).is_between(1, 10) == yes -assert (7.5).is_between(10, 1) == yes -assert (7.5).is_between(100, 200) == no -assert (7.5).is_between(1, 7.5) == yes +assert (16).sqrt() == 4 +assert (17).sqrt() == 4 ``` -## Num.isfinite +## Int.to ```tomo -Num.isfinite : func(n: Num -> Bool) +Int.to : func(first: Int, last: Int, step: Int? = none -> func(->Int?)) ``` -Checks if a number is finite. +Returns an iterator function that iterates over the range of numbers specified. Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number to be checked. | - +first | `Int` | The starting value of the range. | - +last | `Int` | The ending value of the range. | - +step | `Int?` | An optional step size to use. If unspecified or `none`, the step will be inferred to be `+1` if `last >= first`, otherwise `-1`. | `none` -**Return:** `yes` if `n` is finite, `no` otherwise. +**Return:** An iterator function that returns each integer in the given range (inclusive). **Example:** ```tomo -assert (1.0).isfinite() == yes -assert Num.INF.isfinite() == no +iter := (2).to(5) +assert iter() == 2 +assert iter() == 3 +assert iter() == 4 +assert iter() == 5 +assert iter() == none + +assert [x for x in (2).to(5)] == [2, 3, 4, 5] +assert [x for x in (5).to(2)] == [5, 4, 3, 2] +assert [x for x in (2).to(5, step=2)] == [2, 4] ``` -## Num.isinf + +# List +## List.binary_search ```tomo -Num.isinf : func(n: Num -> Bool) +List.binary_search : func(list: [T], by: func(x,y:&T->Int32) = T.compare -> Int) ``` -Checks if a number is infinite. +Performs a binary search on a sorted list. Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number to be checked. | - +list | `[T]` | The sorted list to search. | - +by | `func(x,y:&T->Int32)` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` -**Return:** `yes` if `n` is infinite, `no` otherwise. +**Return:** Assuming the input list is sorted according to the given comparison function, return the index where the given item would be inserted to maintain the sorted order. That is, if the item is found, return its index, otherwise return the place where it would be found if it were inserted and the list were sorted. **Example:** ```tomo -assert Num.INF.isinf() == yes -assert (1.0).isinf() == no +assert [1, 3, 5, 7, 9].binary_search(5) == 3 +assert [1, 3, 5, 7, 9].binary_search(-999) == 1 +assert [1, 3, 5, 7, 9].binary_search(999) == 6 ``` -## Num.j0 +## List.by ```tomo -Num.j0 : func(x: Num -> Num) +List.by : func(list: [T], step: Int -> [T]) ``` -Computes the Bessel function of the first kind of order 0. +Creates a new list with elements spaced by the specified step value. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the Bessel function is to be calculated. | - +list | `[T]` | The original list. | - +step | `Int` | The step value for selecting elements. | - -**Return:** The Bessel function of the first kind of order 0 of `x`. +**Return:** A new list with every `step`-th element from the original list. **Example:** ```tomo -assert (0.0).j0() == 1 +assert [1, 2, 3, 4, 5, 6].by(2) == [1, 3, 5] ``` -## Num.j1 +## List.clear ```tomo -Num.j1 : func(x: Num -> Num) +List.clear : func(list: @[T] -> Void) ``` -Computes the Bessel function of the first kind of order 1. +Clears all elements from the list. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the Bessel function is to be calculated. | - +list | `@[T]` | The mutable reference to the list to be cleared. | - -**Return:** The Bessel function of the first kind of order 1 of `x`. +**Return:** Nothing. **Example:** ```tomo -assert (0.0).j1() == 0 +my_list.clear() ``` -## Num.log +## List.counts ```tomo -Num.log : func(x: Num -> Num) +List.counts : func(list: [T] -> {T=Int}) ``` -Computes the natural logarithm (base $e$) of a number. +Counts the occurrences of each element in the list. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the natural logarithm is to be calculated. | - +list | `[T]` | The list to count elements in. | - -**Return:** The natural logarithm of `x`. +**Return:** A table mapping each element to its count. **Example:** ```tomo -assert Num.E.log() == 1 +assert [10, 20, 30, 30, 30].counts() == {10=1, 20=1, 30=3} ``` -## Num.log10 +## List.find ```tomo -Num.log10 : func(x: Num -> Num) +List.find : func(list: [T], target: T -> Int?) ``` -Computes the base-10 logarithm of a number. +Finds the index of the first occurrence of an element (if any). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the base-10 logarithm is to be calculated. | - +list | `[T]` | The list to search through. | - +target | `T` | The item to search for. | - -**Return:** The base-10 logarithm of `x`. +**Return:** The index of the first occurrence or `none` if not found. **Example:** ```tomo -assert (100.0).log10() == 2 +assert [10, 20, 30, 40, 50].find(20) == 2 +assert [10, 20, 30, 40, 50].find(9999) == none ``` -## Num.log1p +## List.from ```tomo -Num.log1p : func(x: Num -> Num) +List.from : func(list: [T], first: Int -> [T]) ``` -Computes $\log(1 + x)$ for a number. +Returns a slice of the list starting from a specified index. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which $\log(1 + x)$ is to be calculated. | - +list | `[T]` | The original list. | - +first | `Int` | The index to start from. | - -**Return:** The value of $\log(1 + x)$. +**Return:** A new list starting from the specified index. **Example:** ```tomo -assert (1.0).log1p() == 0.6931 +assert [10, 20, 30, 40, 50].from(3) == [30, 40, 50] ``` -## Num.log2 +## List.has ```tomo -Num.log2 : func(x: Num -> Num) +List.has : func(list: [T], target: T -> Bool) ``` -Computes the base-2 logarithm of a number. +Checks if the list has an element. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the base-2 logarithm is to be calculated. | - +list | `[T]` | The list to check. | - +target | `T` | The element to check for. | - -**Return:** The base-2 logarithm of `x`. +**Return:** `yes` if the list has the element, `no` otherwise. **Example:** ```tomo -assert (8.0).log2() == 3 +assert [10, 20, 30].has(20) == yes ``` -## Num.logb +## List.heap_pop ```tomo -Num.logb : func(x: Num -> Num) +List.heap_pop : func(list: @[T], by: func(x,y:&T->Int32) = T.compare -> T?) ``` -Computes the binary exponent (base-2 logarithm) of a number. +Removes and returns the top element of a heap or `none` if the list is empty. By default, this is the *minimum* value in the heap. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the binary exponent is to be calculated. | - +list | `@[T]` | The mutable reference to the heap. | - +by | `func(x,y:&T->Int32)` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` -**Return:** The binary exponent of `x`. +**Return:** The removed top element of the heap or `none` if the list is empty. **Example:** ```tomo -assert (8.0).logb() == 3 +my_heap := [30, 10, 20] +my_heap.heapify() +assert my_heap.heap_pop() == 10 ``` -## Num.mix +## List.heap_push ```tomo -Num.mix : func(amount: Num, x: Num, y: Num -> Num) +List.heap_push : func(list: @[T], item: T, by = T.compare -> Void) ``` -Interpolates between two numbers based on a given amount. +Adds an element to the heap and maintains the heap property. By default, this is a *minimum* heap. Argument | Type | Description | Default ---------|------|-------------|--------- -amount | `Num` | The interpolation factor (between `0` and `1`). | - -x | `Num` | The starting number. | - -y | `Num` | The ending number. | - +list | `@[T]` | The mutable reference to the heap. | - +item | `T` | The item to be added. | - +by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` -**Return:** The interpolated number between `x` and `y` based on `amount`. +**Return:** Nothing. **Example:** ```tomo -assert (0.5).mix(10, 20) == 15 -assert (0.25).mix(10, 20) == 12.5 +my_heap.heap_push(10) ``` -## Num.near +## List.heapify ```tomo -Num.near : func(x: Num, y: Num, ratio: Num = 1e-9, min_epsilon: Num = 1e-9 -> Bool) +List.heapify : func(list: @[T], by: func(x,y:&T->Int32) = T.compare -> Void) ``` -Checks if two numbers are approximately equal within specified tolerances. If two numbers are within an absolute difference or the ratio between the two is small enough, they are considered near each other. +Converts a list into a heap. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The first number. | - -y | `Num` | The second number. | - -ratio | `Num` | The relative tolerance. Default is `1e-9`. | `1e-9` -min_epsilon | `Num` | The absolute tolerance. Default is `1e-9`. | `1e-9` +list | `@[T]` | The mutable reference to the list to be heapified. | - +by | `func(x,y:&T->Int32)` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` -**Return:** `yes` if `x` and `y` are approximately equal within the specified tolerances, `no` otherwise. +**Return:** Nothing. **Example:** ```tomo -assert (1.0).near(1.000000001) == yes -assert (100.0).near(110, ratio=0.1) == yes -assert (5.0).near(5.1, min_epsilon=0.1) == yes +my_heap := [30, 10, 20] +my_heap.heapify() ``` -## Num.nextafter +## List.insert ```tomo -Num.nextafter : func(x: Num, y: Num -> Num) +List.insert : func(list: @[T], item: T, at: Int = 0 -> Void) ``` -Computes the next representable value after a given number towards a specified direction. +Inserts an element at a specified position in the list. + +Since indices are 1-indexed and negative indices mean "starting from the back", an index of `0` means "after the last item". Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The starting number. | - -y | `Num` | The direction towards which to find the next representable value. | - +list | `@[T]` | The mutable reference to the list. | - +item | `T` | The item to be inserted. | - +at | `Int` | The index at which to insert the item. | `0` -**Return:** The next representable value after `x` in the direction of `y`. +**Return:** Nothing. **Example:** ```tomo -assert (1.0).nextafter(1.1) == 1.0000000000000002 +list := [10, 20] +list.insert(30) +assert list == [10, 20, 30] + +list.insert(999, at=2) +assert list == [10, 999, 20, 30] ``` -## Num.parse +## List.insert_all ```tomo -Num.parse : func(text: Text, remainder: &Text? = none -> Num?) +List.insert_all : func(list: @[T], items: [T], at: Int = 0 -> Void) ``` -Converts a text representation of a number into a floating-point number. +Inserts a list of items at a specified position in the list. + +Since indices are 1-indexed and negative indices mean "starting from the back", an index of `0` means "after the last item". Argument | Type | Description | Default ---------|------|-------------|--------- -text | `Text` | The text containing the number. | - -remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none` +list | `@[T]` | The mutable reference to the list. | - +items | `[T]` | The items to be inserted. | - +at | `Int` | The index at which to insert the item. | `0` -**Return:** The number represented by the text or `none` if the entire text can't be parsed as a number. +**Return:** Nothing. **Example:** ```tomo -assert Num.parse("3.14") == 3.14 -assert Num.parse("1e3") == 1000 -assert Num.parse("1.5junk") == none -remainder : Text -assert Num.parse("1.5junk", &remainder) == 1.5 -assert remainder == "junk" +list := [10, 20] +list.insert_all([30, 40]) +assert list == [10, 20, 30, 40] + +list.insert_all([99, 100], at=2) +assert list == [10, 99, 100, 20, 30, 40] ``` -## Num.percent +## List.pop ```tomo -Num.percent : func(n: Num, precision: Num = 0.01 -> Text) +List.pop : func(list: &[T], index: Int = -1 -> T?) ``` -Convert a number into a percentage text with a percent sign. +Removes and returns an item from the list. If the given index is present in the list, the item at that index will be removed and the list will become one element shorter. + +Since negative indices are counted from the back, the default behavior is to pop the last value. Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number to be converted to a percent. | - -precision | `Num` | Round the percentage to this precision level. | `0.01` +list | `&[T]` | The list to remove an item from. | - +index | `Int` | The index from which to remove the item. | `-1` -**Return:** A text representation of the number as a percentage with a percent sign. +**Return:** `none` if the list is empty or the given index does not exist in the list, otherwise the item at the given index. **Example:** ```tomo -assert (0.5).percent() == "50%" -assert (1./3.).percent(2) == "33.33%" -assert (1./3.).percent(2, precision=0.0001) == "33.3333%" -assert (1./3.).percent(2, precision=10.) == "30%" +list := &[10, 20, 30, 40] + +assert list.pop() == 40 +assert list[] == [10, 20, 30] + +assert list.pop(index=2) == 20 +assert list[] == [10, 30] ``` -## Num.rint +## List.random ```tomo -Num.rint : func(x: Num -> Num) +List.random : func(list: [T], random: func(min,max:Int64->Int64)? = none -> T) ``` -Rounds a number to the nearest integer, with ties rounded to the nearest even integer. +Selects a random element from the list. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be rounded. | - +list | `[T]` | The list from which to select a random element. | - +random | `func(min,max:Int64->Int64)?` | If provided, this function will be used to get a random index in the list. Returned values must be between `min` and `max` (inclusive). (Used for deterministic pseudorandom number generation) | `none` -**Return:** The nearest integer value of `x`. +**Return:** A random element from the list. **Example:** ```tomo -assert (3.5).rint() == 4 -assert (2.5).rint() == 2 +assert [10, 20, 30].random() == 20 ``` -## Num.round +## List.remove_at ```tomo -Num.round : func(x: Num -> Num) +List.remove_at : func(list: @[T], at: Int = -1, count: Int = 1 -> Void) ``` -Rounds a number to the nearest whole number integer. +Removes elements from the list starting at a specified index. + +Since negative indices are counted from the back, the default behavior is to remove the last item. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be rounded. | - +list | `@[T]` | The mutable reference to the list. | - +at | `Int` | The index at which to start removing elements. | `-1` +count | `Int` | The number of elements to remove. | `1` -**Return:** The nearest integer value of `x`. +**Return:** Nothing. **Example:** ```tomo -assert (2.3).round() == 2 -assert (2.7).round() == 3 +list := [10, 20, 30, 40, 50] +list.remove_at(2) +assert list == [10, 30, 40, 50] + +list.remove_at(2, count=2) +assert list == [10, 50] ``` -## Num.significand +## List.remove_item ```tomo -Num.significand : func(x: Num -> Num) +List.remove_item : func(list: @[T], item: T, max_count: Int = -1 -> Void) ``` -Extracts the significand (or mantissa) of a number. +Removes all occurrences of a specified item from the list. + +A negative `max_count` means "remove all occurrences". Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number from which to extract the significand. | - +list | `@[T]` | The mutable reference to the list. | - +item | `T` | The item to be removed. | - +max_count | `Int` | The maximum number of occurrences to remove. | `-1` -**Return:** The significand of `x`. +**Return:** Nothing. **Example:** ```tomo -assert (1234.567).significand() == 0.1234567 +list := [10, 20, 10, 20, 30] +list.remove_item(10) +assert list == [20, 20, 30] + +list.remove_item(20, max_count=1) +assert list == [20, 30] ``` -## Num.sin +## List.reversed ```tomo -Num.sin : func(x: Num -> Num) +List.reversed : func(list: [T] -> [T]) ``` -Computes the sine of a number (angle in radians). +Returns a reversed slice of the list. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The angle in radians. | - +list | `[T]` | The list to be reversed. | - -**Return:** The sine of `x`. +**Return:** A slice of the list with elements in reverse order. **Example:** ```tomo -assert (0.0).sin() == 0 +assert [10, 20, 30].reversed() == [30, 20, 10] ``` -## Num.sinh +## List.sample ```tomo -Num.sinh : func(x: Num -> Num) +List.sample : func(list: [T], count: Int, weights: [Float64]? = none, random: func(->Float64)? = none -> [T]) ``` -Computes the hyperbolic sine of a number. +Selects a sample of elements from the list, optionally with weighted probabilities. + +Errors will be raised if any of the following conditions occurs: - The given list has no elements and `count >= 1` - `count < 0` (negative count) - The number of weights provided doesn't match the length of the list. - Any weight in the weights list is negative, infinite, or `NaN` - The sum of the given weights is zero (zero probability for every element). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the hyperbolic sine is to be calculated. | - +list | `[T]` | The list to sample from. | - +count | `Int` | The number of elements to sample. | - +weights | `[Float64]?` | The probability weights for each element in the list. These values do not need to add up to any particular number, they are relative weights. If no weights are given, elements will be sampled with uniform probability. | `none` +random | `func(->Float64)?` | If provided, this function will be used to get random values for sampling the list. The provided function should return random numbers between `0.0` (inclusive) and `1.0` (exclusive). (Used for deterministic pseudorandom number generation) | `none` -**Return:** The hyperbolic sine of `x`. +**Return:** A list of sampled elements from the list. **Example:** ```tomo -assert (0.0).sinh() == 0 +assert [10, 20, 30].sample(2, weights=[90%, 5%, 5%]) == [10, 10] ``` -## Num.sqrt +## List.shuffle ```tomo -Num.sqrt : func(x: Num -> Num) +List.shuffle : func(list: @[T], random: func(min,max:Int64->Int64)? = none -> Void) ``` -Computes the square root of a number. +Shuffles the elements of the list in place. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the square root is to be calculated. | - +list | `@[T]` | The mutable reference to the list to be shuffled. | - +random | `func(min,max:Int64->Int64)?` | If provided, this function will be used to get a random index in the list. Returned values must be between `min` and `max` (inclusive). (Used for deterministic pseudorandom number generation) | `none` -**Return:** The square root of `x`. +**Return:** Nothing. **Example:** ```tomo -assert (16.0).sqrt() == 4 +list.shuffle() ``` -## Num.tan +## List.shuffled ```tomo -Num.tan : func(x: Num -> Num) +List.shuffled : func(list: [T], random: func(min,max:Int64->Int64)? = none -> [T]) ``` -Computes the tangent of a number (angle in radians). +Creates a new list with elements shuffled. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The angle in radians. | - +list | `[T]` | The list to be shuffled. | - +random | `func(min,max:Int64->Int64)?` | If provided, this function will be used to get a random index in the list. Returned values must be between `min` and `max` (inclusive). (Used for deterministic pseudorandom number generation) | `none` -**Return:** The tangent of `x`. +**Return:** A new list with shuffled elements. **Example:** ```tomo -assert (0.0).tan() == 0 +assert [10, 20, 30, 40].shuffled() == [40, 10, 30, 20] ``` -## Num.tanh +## List.slice ```tomo -Num.tanh : func(x: Num -> Num) +List.slice : func(list: [T], from: Int, to: Int -> [T]) ``` -Computes the hyperbolic tangent of a number. +Returns a slice of the list spanning the given indices (inclusive). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the hyperbolic tangent is to be calculated. | - +list | `[T]` | The original list. | - +from | `Int` | The first index to include. | - +to | `Int` | The last index to include. | - -**Return:** The hyperbolic tangent of `x`. +**Return:** A new list spanning the given indices. Note: negative indices are counted from the back of the list, so `-1` refers to the last element, `-2` the second-to-last, and so on. **Example:** ```tomo -assert (0.0).tanh() == 0 +assert [10, 20, 30, 40, 50].slice(2, 4) == [20, 30, 40] +assert [10, 20, 30, 40, 50].slice(-3, -2) == [30, 40] ``` -## Num.tgamma +## List.sort ```tomo -Num.tgamma : func(x: Num -> Num) +List.sort : func(list: @[T], by = T.compare -> Void) ``` -Computes the gamma function of a number. +Sorts the elements of the list in place in ascending order (small to large). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the gamma function is to be calculated. | - +list | `@[T]` | The mutable reference to the list to be sorted. | - +by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` -**Return:** The gamma function of `x`. +**Return:** Nothing. **Example:** ```tomo -assert (1.0).tgamma() == 1 +list := [40, 10, -30, 20] +list.sort() +assert list == [-30, 10, 20, 40] + +list.sort(func(a,b:&Int): a.abs() <> b.abs()) +assert list == [10, 20, -30, 40] ``` -## Num.trunc +## List.sorted ```tomo -Num.trunc : func(x: Num -> Num) +List.sorted : func(list: [T], by = T.compare -> [T]) ``` -Truncates a number to the nearest integer towards zero. +Creates a new list with elements sorted. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be truncated. | - +list | `[T]` | The list to be sorted. | - +by | `` | The comparison function used to determine order. If not specified, the default comparison function for the item type will be used. | `T.compare` -**Return:** The integer part of `x` towards zero. +**Return:** A new list with sorted elements. **Example:** ```tomo -assert (3.7).trunc() == 3 -assert (-3.7).trunc() == -3 +assert [40, 10, -30, 20].sorted() == [-30, 10, 20, 40] +assert [40, 10, -30, 20].sorted( + func(a,b:&Int): a.abs() <> b.abs() +) == [10, 20, -30, 40] ``` -## Num.with_precision +## List.to ```tomo -Num.with_precision : func(n: Num, precision: Num -> Num) +List.to : func(list: [T], last: Int -> [T]) ``` -Round a number to the given precision level (specified as `10`, `.1`, `.001` etc). +Returns a slice of the list from the start of the original list up to a specified index (inclusive). Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number to be rounded to a given precision. | - -precision | `Num` | The precision to which the number should be rounded. | - +list | `[T]` | The original list. | - +last | `Int` | The index up to which elements should be included. | - -**Return:** The number, rounded to the given precision level. +**Return:** A new list containing elements from the start up to the specified index. **Example:** ```tomo -assert (0.1234567).with_precision(0.01) == 0.12 -assert (123456.).with_precision(100) == 123500 -assert (1234567.).with_precision(5) == 1234565 +assert [10, 20, 30, 40, 50].to(3) == [10, 20, 30] +assert [10, 20, 30, 40, 50].to(-2) == [10, 20, 30, 40] ``` -## Num.y0 +## List.unique ```tomo -Num.y0 : func(x: Num -> Num) +List.unique : func(list: [T] -> {T}) ``` -Computes the Bessel function of the second kind of order 0. +Returns a set of the unique elements of the list. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the Bessel function is to be calculated. | - +list | `[T]` | The list to process. | - -**Return:** The Bessel function of the second kind of order 0 of `x`. +**Return:** A set of the unique elements from the list. **Example:** ```tomo -assert (1.0).y0() == -0.7652 +assert [10, 20, 10, 10, 30].unique() == {10, 20, 30} ``` -## Num.y1 +## List.where ```tomo -Num.y1 : func(x: Num -> Num) +List.where : func(list: [T], predicate: func(item:&T -> Bool) -> Int) ``` -Computes the Bessel function of the second kind of order 1. +Find the index of the first item that matches a predicate function (if any). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the Bessel function is to be calculated. | - +list | `[T]` | The list to search through. | - +predicate | `func(item:&T -> Bool)` | A function that returns `yes` if the item's index should be returned or `no` if it should not. | - -**Return:** The Bessel function of the second kind of order 1 of `x`. +**Return:** Returns the index of the first item where the predicate is true or `none` if no item matches. **Example:** ```tomo -assert (1.0).y1() == 0.4401 +assert [4, 5, 6].where(func(i:&Int): i.is_prime()) == 5 +assert [4, 6, 8].find(func(i:&Int): i.is_prime()) == none ``` diff --git a/api/builtins.md b/api/builtins.md index 2ef14275..2dc2ba9e 100644 --- a/api/builtins.md +++ b/api/builtins.md @@ -187,14 +187,14 @@ setenv("FOOBAR", "xyz") ## sleep ```tomo -sleep : func(seconds: Num -> Void) +sleep : func(seconds: Float64 -> Void) ``` Pause execution for a given number of seconds. Argument | Type | Description | Default ---------|------|-------------|--------- -seconds | `Num` | How many seconds to sleep for. | - +seconds | `Float64` | How many seconds to sleep for. | - **Return:** Nothing. diff --git a/api/builtins.yaml b/api/builtins.yaml index af7c9319..aa2eef30 100644 --- a/api/builtins.yaml +++ b/api/builtins.yaml @@ -174,7 +174,7 @@ sleep: Nothing. args: seconds: - type: 'Num' + type: 'Float64' description: > How many seconds to sleep for. example: | diff --git a/api/nums.md b/api/floats.md index 1bad194d..a6d78b78 100644 --- a/api/nums.md +++ b/api/floats.md @@ -2,130 +2,130 @@ # Builtins -# Num -## Num.1_PI +# Float +## Float.1_PI ```tomo -Num.1_PI : Num +Float.1_PI : Float ``` The constant $\frac{1}{\pi}$. -## Num.2_PI +## Float.2_PI ```tomo -Num.2_PI : Num +Float.2_PI : Float ``` The constant $2 \times \pi$. -## Num.2_SQRTPI +## Float.2_SQRTPI ```tomo -Num.2_SQRTPI : Num +Float.2_SQRTPI : Float ``` The constant $2 \times \sqrt{\pi}$. -## Num.E +## Float.E ```tomo -Num.E : Num +Float.E : Float ``` The base of the natural logarithm ($e$). -## Num.INF +## Float.INF ```tomo -Num.INF : Num +Float.INF : Float ``` Positive infinity. -## Num.LN10 +## Float.LN10 ```tomo -Num.LN10 : Num +Float.LN10 : Float ``` The natural logarithm of 10. -## Num.LN2 +## Float.LN2 ```tomo -Num.LN2 : Num +Float.LN2 : Float ``` The natural logarithm of 2. -## Num.LOG2E +## Float.LOG2E ```tomo -Num.LOG2E : Num +Float.LOG2E : Float ``` The base 2 logarithm of $e$ -## Num.PI +## Float.PI ```tomo -Num.PI : Num +Float.PI : Float ``` Pi ($\pi$). -## Num.PI_2 +## Float.PI_2 ```tomo -Num.PI_2 : Num +Float.PI_2 : Float ``` $\frac{\pi}{2}$ -## Num.PI_4 +## Float.PI_4 ```tomo -Num.PI_4 : Num +Float.PI_4 : Float ``` $\frac{\pi}{4}$ -## Num.SQRT1_2 +## Float.SQRT1_2 ```tomo -Num.SQRT1_2 : Num +Float.SQRT1_2 : Float ``` $\sqrt{\frac{1}{2}}$ -## Num.SQRT2 +## Float.SQRT2 ```tomo -Num.SQRT2 : Num +Float.SQRT2 : Float ``` $\sqrt{2}$ -## Num.TAU +## Float.TAU ```tomo -Num.TAU : Num +Float.TAU : Float ``` Tau ($2 \times \pi$) -## Num.abs +## Float.abs ```tomo -Num.abs : func(n: Num -> Num) +Float.abs : func(n: Float -> Float) ``` Calculates the absolute value of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number whose absolute value is to be computed. | - +n | `Float` | The number whose absolute value is to be computed. | - **Return:** The absolute value of `n`. @@ -135,17 +135,17 @@ n | `Num` | The number whose absolute value is to be computed. | - assert (-3.5).abs() == 3.5 ``` -## Num.acos +## Float.acos ```tomo -Num.acos : func(x: Num -> Num) +Float.acos : func(x: Float -> Float) ``` Computes the arc cosine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the arc cosine is to be calculated. | - +x | `Float` | The number for which the arc cosine is to be calculated. | - **Return:** The arc cosine of `x` in radians. @@ -155,17 +155,17 @@ x | `Num` | The number for which the arc cosine is to be calculated. | - assert (0.0).acos() == 1.5708 ``` -## Num.acosh +## Float.acosh ```tomo -Num.acosh : func(x: Num -> Num) +Float.acosh : func(x: Float -> Float) ``` Computes the inverse hyperbolic cosine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the inverse hyperbolic cosine is to be calculated. | - +x | `Float` | The number for which the inverse hyperbolic cosine is to be calculated. | - **Return:** The inverse hyperbolic cosine of `x`. @@ -175,17 +175,17 @@ x | `Num` | The number for which the inverse hyperbolic cosine is to be calculat assert (1.0).acosh() == 0 ``` -## Num.asin +## Float.asin ```tomo -Num.asin : func(x: Num -> Num) +Float.asin : func(x: Float -> Float) ``` Computes the arc sine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the arc sine is to be calculated. | - +x | `Float` | The number for which the arc sine is to be calculated. | - **Return:** The arc sine of `x` in radians. @@ -195,17 +195,17 @@ x | `Num` | The number for which the arc sine is to be calculated. | - assert (0.5).asin() == 0.5236 ``` -## Num.asinh +## Float.asinh ```tomo -Num.asinh : func(x: Num -> Num) +Float.asinh : func(x: Float -> Float) ``` Computes the inverse hyperbolic sine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the inverse hyperbolic sine is to be calculated. | - +x | `Float` | The number for which the inverse hyperbolic sine is to be calculated. | - **Return:** The inverse hyperbolic sine of `x`. @@ -215,17 +215,17 @@ x | `Num` | The number for which the inverse hyperbolic sine is to be calculated assert (0.0).asinh() == 0 ``` -## Num.atan +## Float.atan ```tomo -Num.atan : func(x: Num -> Num) +Float.atan : func(x: Float -> Float) ``` Computes the arc tangent of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the arc tangent is to be calculated. | - +x | `Float` | The number for which the arc tangent is to be calculated. | - **Return:** The arc tangent of `x` in radians. @@ -235,38 +235,38 @@ x | `Num` | The number for which the arc tangent is to be calculated. | - assert (1.0).atan() == 0.7854 ``` -## Num.atan2 +## Float.atan2 ```tomo -Num.atan2 : func(x: Num, y: Num -> Num) +Float.atan2 : func(x: Float, y: Float -> Float) ``` Computes the arc tangent of the quotient of two numbers. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The numerator. | - -y | `Num` | The denominator. | - +x | `Float` | The numerator. | - +y | `Float` | The denominator. | - **Return:** The arc tangent of `x/y` in radians. **Example:** ```tomo -assert Num.atan2(1, 1) == 0.7854 +assert Float.atan2(1, 1) == 0.7854 ``` -## Num.atanh +## Float.atanh ```tomo -Num.atanh : func(x: Num -> Num) +Float.atanh : func(x: Float -> Float) ``` Computes the inverse hyperbolic tangent of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the inverse hyperbolic tangent is to be calculated. | - +x | `Float` | The number for which the inverse hyperbolic tangent is to be calculated. | - **Return:** The inverse hyperbolic tangent of `x`. @@ -276,17 +276,17 @@ x | `Num` | The number for which the inverse hyperbolic tangent is to be calcula assert (0.5).atanh() == 0.5493 ``` -## Num.cbrt +## Float.cbrt ```tomo -Num.cbrt : func(x: Num -> Num) +Float.cbrt : func(x: Float -> Float) ``` Computes the cube root of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the cube root is to be calculated. | - +x | `Float` | The number for which the cube root is to be calculated. | - **Return:** The cube root of `x`. @@ -296,17 +296,17 @@ x | `Num` | The number for which the cube root is to be calculated. | - assert (27.0).cbrt() == 3 ``` -## Num.ceil +## Float.ceil ```tomo -Num.ceil : func(x: Num -> Num) +Float.ceil : func(x: Float -> Float) ``` Rounds a number up to the nearest integer. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be rounded up. | - +x | `Float` | The number to be rounded up. | - **Return:** The smallest integer greater than or equal to `x`. @@ -316,19 +316,19 @@ x | `Num` | The number to be rounded up. | - assert (3.2).ceil() == 4 ``` -## Num.clamped +## Float.clamped ```tomo -Num.clamped : func(x: Num, low: Num, high: Num -> Num) +Float.clamped : func(x: Float, low: Float, high: Float -> Float) ``` Returns the given number clamped between two values so that it is within that range. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to clamp. | - -low | `Num` | The lowest value the result can take. | - -high | `Num` | The highest value the result can take. | - +x | `Float` | The number to clamp. | - +low | `Float` | The lowest value the result can take. | - +high | `Float` | The highest value the result can take. | - **Return:** The first argument clamped between the other two arguments. @@ -338,18 +338,18 @@ high | `Num` | The highest value the result can take. | - assert (2.5).clamped(5.5, 10.5) == 5.5 ``` -## Num.copysign +## Float.copysign ```tomo -Num.copysign : func(x: Num, y: Num -> Num) +Float.copysign : func(x: Float, y: Float -> Float) ``` Copies the sign of one number to another. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number whose magnitude will be copied. | - -y | `Num` | The number whose sign will be copied. | - +x | `Float` | The number whose magnitude will be copied. | - +y | `Float` | The number whose sign will be copied. | - **Return:** A number with the magnitude of `x` and the sign of `y`. @@ -359,17 +359,17 @@ y | `Num` | The number whose sign will be copied. | - assert (3.0).copysign(-1) == -3 ``` -## Num.cos +## Float.cos ```tomo -Num.cos : func(x: Num -> Num) +Float.cos : func(x: Float -> Float) ``` Computes the cosine of a number (angle in radians). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The angle in radians. | - +x | `Float` | The angle in radians. | - **Return:** The cosine of `x`. @@ -379,17 +379,17 @@ x | `Num` | The angle in radians. | - assert (0.0).cos() == 1 ``` -## Num.cosh +## Float.cosh ```tomo -Num.cosh : func(x: Num -> Num) +Float.cosh : func(x: Float -> Float) ``` Computes the hyperbolic cosine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the hyperbolic cosine is to be calculated. | - +x | `Float` | The number for which the hyperbolic cosine is to be calculated. | - **Return:** The hyperbolic cosine of `x`. @@ -399,17 +399,17 @@ x | `Num` | The number for which the hyperbolic cosine is to be calculated. | - assert (0.0).cosh() == 1 ``` -## Num.erf +## Float.erf ```tomo -Num.erf : func(x: Num -> Num) +Float.erf : func(x: Float -> Float) ``` Computes the error function of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the error function is to be calculated. | - +x | `Float` | The number for which the error function is to be calculated. | - **Return:** The error function of `x`. @@ -419,17 +419,17 @@ x | `Num` | The number for which the error function is to be calculated. | - assert (0.0).erf() == 0 ``` -## Num.erfc +## Float.erfc ```tomo -Num.erfc : func(x: Num -> Num) +Float.erfc : func(x: Float -> Float) ``` Computes the complementary error function of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the complementary error function is to be calculated. | - +x | `Float` | The number for which the complementary error function is to be calculated. | - **Return:** The complementary error function of `x`. @@ -439,17 +439,17 @@ x | `Num` | The number for which the complementary error function is to be calcu assert (0.0).erfc() == 1 ``` -## Num.exp +## Float.exp ```tomo -Num.exp : func(x: Num -> Num) +Float.exp : func(x: Float -> Float) ``` Computes the exponential function $e^x$ for a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The exponent. | - +x | `Float` | The exponent. | - **Return:** The value of $e^x$. @@ -459,17 +459,17 @@ x | `Num` | The exponent. | - assert (1.0).exp() == 2.7183 ``` -## Num.exp2 +## Float.exp2 ```tomo -Num.exp2 : func(x: Num -> Num) +Float.exp2 : func(x: Float -> Float) ``` Computes $2^x$ for a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The exponent. | - +x | `Float` | The exponent. | - **Return:** The value of $2^x$. @@ -479,17 +479,17 @@ x | `Num` | The exponent. | - assert (3.0).exp2() == 8 ``` -## Num.expm1 +## Float.expm1 ```tomo -Num.expm1 : func(x: Num -> Num) +Float.expm1 : func(x: Float -> Float) ``` Computes $e^x - 1$ for a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The exponent. | - +x | `Float` | The exponent. | - **Return:** The value of $e^x - 1$. @@ -499,18 +499,18 @@ x | `Num` | The exponent. | - assert (1.0).expm1() == 1.7183 ``` -## Num.fdim +## Float.fdim ```tomo -Num.fdim : func(x: Num, y: Num -> Num) +Float.fdim : func(x: Float, y: Float -> Float) ``` Computes the positive difference between two numbers. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The first number. | - -y | `Num` | The second number. | - +x | `Float` | The first number. | - +y | `Float` | The second number. | - **Return:** The positive difference $\max(0, x - y)$. @@ -522,17 +522,17 @@ fd assert (5.0).fdim(3) == 2 ``` -## Num.floor +## Float.floor ```tomo -Num.floor : func(x: Num -> Num) +Float.floor : func(x: Float -> Float) ``` Rounds a number down to the nearest integer. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be rounded down. | - +x | `Float` | The number to be rounded down. | - **Return:** The largest integer less than or equal to `x`. @@ -542,38 +542,38 @@ x | `Num` | The number to be rounded down. | - assert (3.7).floor() == 3 ``` -## Num.hypot +## Float.hypot ```tomo -Num.hypot : func(x: Num, y: Num -> Num) +Float.hypot : func(x: Float, y: Float -> Float) ``` Computes the Euclidean norm, $\sqrt{x^2 + y^2}$, of two numbers. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The first number. | - -y | `Num` | The second number. | - +x | `Float` | The first number. | - +y | `Float` | The second number. | - **Return:** The Euclidean norm of `x` and `y`. **Example:** ```tomo -assert Num.hypot(3, 4) == 5 +assert Float.hypot(3, 4) == 5 ``` -## Num.is_between +## Float.is_between ```tomo -Num.is_between : func(x: Num, low: Num, high: Num -> Bool) +Float.is_between : func(x: Float, low: Float, high: Float -> Bool) ``` Determines if a number is between two numbers (inclusive). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The integer to be checked. | - +x | `Float` | The integer to be checked. | - low | `Num` | One end of the range to check (inclusive). | - high | `Num` | The other end of the range to check (inclusive). | - @@ -588,17 +588,17 @@ assert (7.5).is_between(100, 200) == no assert (7.5).is_between(1, 7.5) == yes ``` -## Num.isfinite +## Float.isfinite ```tomo -Num.isfinite : func(n: Num -> Bool) +Float.isfinite : func(n: Float -> Bool) ``` Checks if a number is finite. Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number to be checked. | - +n | `Float` | The number to be checked. | - **Return:** `yes` if `n` is finite, `no` otherwise. @@ -606,41 +606,41 @@ n | `Num` | The number to be checked. | - **Example:** ```tomo assert (1.0).isfinite() == yes -assert Num.INF.isfinite() == no +assert Float.INF.isfinite() == no ``` -## Num.isinf +## Float.isinf ```tomo -Num.isinf : func(n: Num -> Bool) +Float.isinf : func(n: Float -> Bool) ``` Checks if a number is infinite. Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number to be checked. | - +n | `Float` | The number to be checked. | - **Return:** `yes` if `n` is infinite, `no` otherwise. **Example:** ```tomo -assert Num.INF.isinf() == yes +assert Float.INF.isinf() == yes assert (1.0).isinf() == no ``` -## Num.j0 +## Float.j0 ```tomo -Num.j0 : func(x: Num -> Num) +Float.j0 : func(x: Float -> Float) ``` Computes the Bessel function of the first kind of order 0. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the Bessel function is to be calculated. | - +x | `Float` | The number for which the Bessel function is to be calculated. | - **Return:** The Bessel function of the first kind of order 0 of `x`. @@ -650,17 +650,17 @@ x | `Num` | The number for which the Bessel function is to be calculated. | - assert (0.0).j0() == 1 ``` -## Num.j1 +## Float.j1 ```tomo -Num.j1 : func(x: Num -> Num) +Float.j1 : func(x: Float -> Float) ``` Computes the Bessel function of the first kind of order 1. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the Bessel function is to be calculated. | - +x | `Float` | The number for which the Bessel function is to be calculated. | - **Return:** The Bessel function of the first kind of order 1 of `x`. @@ -670,37 +670,37 @@ x | `Num` | The number for which the Bessel function is to be calculated. | - assert (0.0).j1() == 0 ``` -## Num.log +## Float.log ```tomo -Num.log : func(x: Num -> Num) +Float.log : func(x: Float -> Float) ``` Computes the natural logarithm (base $e$) of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the natural logarithm is to be calculated. | - +x | `Float` | The number for which the natural logarithm is to be calculated. | - **Return:** The natural logarithm of `x`. **Example:** ```tomo -assert Num.E.log() == 1 +assert Float.E.log() == 1 ``` -## Num.log10 +## Float.log10 ```tomo -Num.log10 : func(x: Num -> Num) +Float.log10 : func(x: Float -> Float) ``` Computes the base-10 logarithm of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the base-10 logarithm is to be calculated. | - +x | `Float` | The number for which the base-10 logarithm is to be calculated. | - **Return:** The base-10 logarithm of `x`. @@ -710,17 +710,17 @@ x | `Num` | The number for which the base-10 logarithm is to be calculated. | - assert (100.0).log10() == 2 ``` -## Num.log1p +## Float.log1p ```tomo -Num.log1p : func(x: Num -> Num) +Float.log1p : func(x: Float -> Float) ``` Computes $\log(1 + x)$ for a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which $\log(1 + x)$ is to be calculated. | - +x | `Float` | The number for which $\log(1 + x)$ is to be calculated. | - **Return:** The value of $\log(1 + x)$. @@ -730,17 +730,17 @@ x | `Num` | The number for which $\log(1 + x)$ is to be calculated. | - assert (1.0).log1p() == 0.6931 ``` -## Num.log2 +## Float.log2 ```tomo -Num.log2 : func(x: Num -> Num) +Float.log2 : func(x: Float -> Float) ``` Computes the base-2 logarithm of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the base-2 logarithm is to be calculated. | - +x | `Float` | The number for which the base-2 logarithm is to be calculated. | - **Return:** The base-2 logarithm of `x`. @@ -750,17 +750,17 @@ x | `Num` | The number for which the base-2 logarithm is to be calculated. | - assert (8.0).log2() == 3 ``` -## Num.logb +## Float.logb ```tomo -Num.logb : func(x: Num -> Num) +Float.logb : func(x: Float -> Float) ``` Computes the binary exponent (base-2 logarithm) of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the binary exponent is to be calculated. | - +x | `Float` | The number for which the binary exponent is to be calculated. | - **Return:** The binary exponent of `x`. @@ -770,19 +770,19 @@ x | `Num` | The number for which the binary exponent is to be calculated. | - assert (8.0).logb() == 3 ``` -## Num.mix +## Float.mix ```tomo -Num.mix : func(amount: Num, x: Num, y: Num -> Num) +Float.mix : func(amount: Float, x: Float, y: Float -> Float) ``` Interpolates between two numbers based on a given amount. Argument | Type | Description | Default ---------|------|-------------|--------- -amount | `Num` | The interpolation factor (between `0` and `1`). | - -x | `Num` | The starting number. | - -y | `Num` | The ending number. | - +amount | `Float` | The interpolation factor (between `0` and `1`). | - +x | `Float` | The starting number. | - +y | `Float` | The ending number. | - **Return:** The interpolated number between `x` and `y` based on `amount`. @@ -793,20 +793,20 @@ assert (0.5).mix(10, 20) == 15 assert (0.25).mix(10, 20) == 12.5 ``` -## Num.near +## Float.near ```tomo -Num.near : func(x: Num, y: Num, ratio: Num = 1e-9, min_epsilon: Num = 1e-9 -> Bool) +Float.near : func(x: Float, y: Float, ratio: Float = 1e-9, min_epsilon: Float = 1e-9 -> Bool) ``` Checks if two numbers are approximately equal within specified tolerances. If two numbers are within an absolute difference or the ratio between the two is small enough, they are considered near each other. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The first number. | - -y | `Num` | The second number. | - -ratio | `Num` | The relative tolerance. Default is `1e-9`. | `1e-9` -min_epsilon | `Num` | The absolute tolerance. Default is `1e-9`. | `1e-9` +x | `Float` | The first number. | - +y | `Float` | The second number. | - +ratio | `Float` | The relative tolerance. Default is `1e-9`. | `1e-9` +min_epsilon | `Float` | The absolute tolerance. Default is `1e-9`. | `1e-9` **Return:** `yes` if `x` and `y` are approximately equal within the specified tolerances, `no` otherwise. @@ -818,18 +818,18 @@ assert (100.0).near(110, ratio=0.1) == yes assert (5.0).near(5.1, min_epsilon=0.1) == yes ``` -## Num.nextafter +## Float.nextafter ```tomo -Num.nextafter : func(x: Num, y: Num -> Num) +Float.nextafter : func(x: Float, y: Float -> Float) ``` Computes the next representable value after a given number towards a specified direction. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The starting number. | - -y | `Num` | The direction towards which to find the next representable value. | - +x | `Float` | The starting number. | - +y | `Float` | The direction towards which to find the next representable value. | - **Return:** The next representable value after `x` in the direction of `y`. @@ -839,10 +839,10 @@ y | `Num` | The direction towards which to find the next representable value. | assert (1.0).nextafter(1.1) == 1.0000000000000002 ``` -## Num.parse +## Float.parse ```tomo -Num.parse : func(text: Text, remainder: &Text? = none -> Num?) +Float.parse : func(text: Text, remainder: &Text? = none -> Float?) ``` Converts a text representation of a number into a floating-point number. @@ -857,26 +857,26 @@ remainder | `&Text?` | If non-none, this argument will be set to the remainder o **Example:** ```tomo -assert Num.parse("3.14") == 3.14 -assert Num.parse("1e3") == 1000 -assert Num.parse("1.5junk") == none +assert Float.parse("3.14") == 3.14 +assert Float.parse("1e3") == 1000 +assert Float.parse("1.5junk") == none remainder : Text -assert Num.parse("1.5junk", &remainder) == 1.5 +assert Float.parse("1.5junk", &remainder) == 1.5 assert remainder == "junk" ``` -## Num.percent +## Float.percent ```tomo -Num.percent : func(n: Num, precision: Num = 0.01 -> Text) +Float.percent : func(n: Float, precision: Float = 0.01 -> Text) ``` Convert a number into a percentage text with a percent sign. Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number to be converted to a percent. | - -precision | `Num` | Round the percentage to this precision level. | `0.01` +n | `Float` | The number to be converted to a percent. | - +precision | `Float` | Round the percentage to this precision level. | `0.01` **Return:** A text representation of the number as a percentage with a percent sign. @@ -889,17 +889,17 @@ assert (1./3.).percent(2, precision=0.0001) == "33.3333%" assert (1./3.).percent(2, precision=10.) == "30%" ``` -## Num.rint +## Float.rint ```tomo -Num.rint : func(x: Num -> Num) +Float.rint : func(x: Float -> Float) ``` Rounds a number to the nearest integer, with ties rounded to the nearest even integer. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be rounded. | - +x | `Float` | The number to be rounded. | - **Return:** The nearest integer value of `x`. @@ -910,17 +910,17 @@ assert (3.5).rint() == 4 assert (2.5).rint() == 2 ``` -## Num.round +## Float.round ```tomo -Num.round : func(x: Num -> Num) +Float.round : func(x: Float -> Float) ``` Rounds a number to the nearest whole number integer. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be rounded. | - +x | `Float` | The number to be rounded. | - **Return:** The nearest integer value of `x`. @@ -931,17 +931,17 @@ assert (2.3).round() == 2 assert (2.7).round() == 3 ``` -## Num.significand +## Float.significand ```tomo -Num.significand : func(x: Num -> Num) +Float.significand : func(x: Float -> Float) ``` Extracts the significand (or mantissa) of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number from which to extract the significand. | - +x | `Float` | The number from which to extract the significand. | - **Return:** The significand of `x`. @@ -951,17 +951,17 @@ x | `Num` | The number from which to extract the significand. | - assert (1234.567).significand() == 0.1234567 ``` -## Num.sin +## Float.sin ```tomo -Num.sin : func(x: Num -> Num) +Float.sin : func(x: Float -> Float) ``` Computes the sine of a number (angle in radians). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The angle in radians. | - +x | `Float` | The angle in radians. | - **Return:** The sine of `x`. @@ -971,17 +971,17 @@ x | `Num` | The angle in radians. | - assert (0.0).sin() == 0 ``` -## Num.sinh +## Float.sinh ```tomo -Num.sinh : func(x: Num -> Num) +Float.sinh : func(x: Float -> Float) ``` Computes the hyperbolic sine of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the hyperbolic sine is to be calculated. | - +x | `Float` | The number for which the hyperbolic sine is to be calculated. | - **Return:** The hyperbolic sine of `x`. @@ -991,17 +991,17 @@ x | `Num` | The number for which the hyperbolic sine is to be calculated. | - assert (0.0).sinh() == 0 ``` -## Num.sqrt +## Float.sqrt ```tomo -Num.sqrt : func(x: Num -> Num) +Float.sqrt : func(x: Float -> Float) ``` Computes the square root of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the square root is to be calculated. | - +x | `Float` | The number for which the square root is to be calculated. | - **Return:** The square root of `x`. @@ -1011,17 +1011,17 @@ x | `Num` | The number for which the square root is to be calculated. | - assert (16.0).sqrt() == 4 ``` -## Num.tan +## Float.tan ```tomo -Num.tan : func(x: Num -> Num) +Float.tan : func(x: Float -> Float) ``` Computes the tangent of a number (angle in radians). Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The angle in radians. | - +x | `Float` | The angle in radians. | - **Return:** The tangent of `x`. @@ -1031,17 +1031,17 @@ x | `Num` | The angle in radians. | - assert (0.0).tan() == 0 ``` -## Num.tanh +## Float.tanh ```tomo -Num.tanh : func(x: Num -> Num) +Float.tanh : func(x: Float -> Float) ``` Computes the hyperbolic tangent of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the hyperbolic tangent is to be calculated. | - +x | `Float` | The number for which the hyperbolic tangent is to be calculated. | - **Return:** The hyperbolic tangent of `x`. @@ -1051,17 +1051,17 @@ x | `Num` | The number for which the hyperbolic tangent is to be calculated. | assert (0.0).tanh() == 0 ``` -## Num.tgamma +## Float.tgamma ```tomo -Num.tgamma : func(x: Num -> Num) +Float.tgamma : func(x: Float -> Float) ``` Computes the gamma function of a number. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the gamma function is to be calculated. | - +x | `Float` | The number for which the gamma function is to be calculated. | - **Return:** The gamma function of `x`. @@ -1071,17 +1071,17 @@ x | `Num` | The number for which the gamma function is to be calculated. | - assert (1.0).tgamma() == 1 ``` -## Num.trunc +## Float.trunc ```tomo -Num.trunc : func(x: Num -> Num) +Float.trunc : func(x: Float -> Float) ``` Truncates a number to the nearest integer towards zero. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number to be truncated. | - +x | `Float` | The number to be truncated. | - **Return:** The integer part of `x` towards zero. @@ -1092,18 +1092,18 @@ assert (3.7).trunc() == 3 assert (-3.7).trunc() == -3 ``` -## Num.with_precision +## Float.with_precision ```tomo -Num.with_precision : func(n: Num, precision: Num -> Num) +Float.with_precision : func(n: Float, precision: Float -> Float) ``` Round a number to the given precision level (specified as `10`, `.1`, `.001` etc). Argument | Type | Description | Default ---------|------|-------------|--------- -n | `Num` | The number to be rounded to a given precision. | - -precision | `Num` | The precision to which the number should be rounded. | - +n | `Float` | The number to be rounded to a given precision. | - +precision | `Float` | The precision to which the number should be rounded. | - **Return:** The number, rounded to the given precision level. @@ -1115,17 +1115,17 @@ assert (123456.).with_precision(100) == 123500 assert (1234567.).with_precision(5) == 1234565 ``` -## Num.y0 +## Float.y0 ```tomo -Num.y0 : func(x: Num -> Num) +Float.y0 : func(x: Float -> Float) ``` Computes the Bessel function of the second kind of order 0. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the Bessel function is to be calculated. | - +x | `Float` | The number for which the Bessel function is to be calculated. | - **Return:** The Bessel function of the second kind of order 0 of `x`. @@ -1135,17 +1135,17 @@ x | `Num` | The number for which the Bessel function is to be calculated. | - assert (1.0).y0() == -0.7652 ``` -## Num.y1 +## Float.y1 ```tomo -Num.y1 : func(x: Num -> Num) +Float.y1 : func(x: Float -> Float) ``` Computes the Bessel function of the second kind of order 1. Argument | Type | Description | Default ---------|------|-------------|--------- -x | `Num` | The number for which the Bessel function is to be calculated. | - +x | `Float` | The number for which the Bessel function is to be calculated. | - **Return:** The Bessel function of the second kind of order 1 of `x`. diff --git a/api/nums.yaml b/api/floats.yaml index 28714ab9..da053d2c 100644 --- a/api/nums.yaml +++ b/api/floats.yaml @@ -1,339 +1,339 @@ -Num.abs: +Float.abs: short: absolute value description: > Calculates the absolute value of a number. return: - type: 'Num' + type: 'Float' description: > The absolute value of `n`. args: n: - type: 'Num' + type: 'Float' description: > The number whose absolute value is to be computed. example: | assert (-3.5).abs() == 3.5 -Num.acos: +Float.acos: short: arc cosine description: > Computes the arc cosine of a number. return: - type: 'Num' + type: 'Float' description: > The arc cosine of `x` in radians. args: x: - type: 'Num' + type: 'Float' description: > The number for which the arc cosine is to be calculated. example: | assert (0.0).acos() == 1.5708 -Num.acosh: +Float.acosh: short: arc hyperbolic cosine description: > Computes the inverse hyperbolic cosine of a number. return: - type: 'Num' + type: 'Float' description: > The inverse hyperbolic cosine of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the inverse hyperbolic cosine is to be calculated. example: | assert (1.0).acosh() == 0 -Num.asin: +Float.asin: short: arc sine description: > Computes the arc sine of a number. return: - type: 'Num' + type: 'Float' description: > The arc sine of `x` in radians. args: x: - type: 'Num' + type: 'Float' description: > The number for which the arc sine is to be calculated. example: | assert (0.5).asin() == 0.5236 -Num.asinh: +Float.asinh: short: arc hyperbolic sine description: > Computes the inverse hyperbolic sine of a number. return: - type: 'Num' + type: 'Float' description: > The inverse hyperbolic sine of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the inverse hyperbolic sine is to be calculated. example: | assert (0.0).asinh() == 0 -Num.atan: +Float.atan: short: arc tangent description: > Computes the arc tangent of a number. return: - type: 'Num' + type: 'Float' description: > The arc tangent of `x` in radians. args: x: - type: 'Num' + type: 'Float' description: > The number for which the arc tangent is to be calculated. example: | assert (1.0).atan() == 0.7854 -Num.atan2: +Float.atan2: short: arc tangent from 2 variables description: > Computes the arc tangent of the quotient of two numbers. return: - type: 'Num' + type: 'Float' description: > The arc tangent of `x/y` in radians. args: x: - type: 'Num' + type: 'Float' description: > The numerator. y: - type: 'Num' + type: 'Float' description: > The denominator. example: | - assert Num.atan2(1, 1) == 0.7854 + assert Float.atan2(1, 1) == 0.7854 -Num.atanh: +Float.atanh: short: arc hyperbolic tangent. description: > Computes the inverse hyperbolic tangent of a number. return: - type: 'Num' + type: 'Float' description: > The inverse hyperbolic tangent of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the inverse hyperbolic tangent is to be calculated. example: | assert (0.5).atanh() == 0.5493 -Num.cbrt: +Float.cbrt: short: cube root description: > Computes the cube root of a number. return: - type: 'Num' + type: 'Float' description: > The cube root of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the cube root is to be calculated. example: | assert (27.0).cbrt() == 3 -Num.ceil: +Float.ceil: short: ceiling function description: > Rounds a number up to the nearest integer. return: - type: 'Num' + type: 'Float' description: > The smallest integer greater than or equal to `x`. args: x: - type: 'Num' + type: 'Float' description: > The number to be rounded up. example: | assert (3.2).ceil() == 4 -Num.clamped: +Float.clamped: short: clamp a number description: > Returns the given number clamped between two values so that it is within that range. return: - type: 'Num' + type: 'Float' description: > The first argument clamped between the other two arguments. args: x: - type: 'Num' + type: 'Float' description: > The number to clamp. low: - type: 'Num' + type: 'Float' description: > The lowest value the result can take. high: - type: 'Num' + type: 'Float' description: > The highest value the result can take. example: | assert (2.5).clamped(5.5, 10.5) == 5.5 -Num.copysign: +Float.copysign: short: copy a number's sign description: > Copies the sign of one number to another. return: - type: 'Num' + type: 'Float' description: > A number with the magnitude of `x` and the sign of `y`. args: x: - type: 'Num' + type: 'Float' description: > The number whose magnitude will be copied. y: - type: 'Num' + type: 'Float' description: > The number whose sign will be copied. example: | assert (3.0).copysign(-1) == -3 -Num.cos: +Float.cos: short: cosine description: > Computes the cosine of a number (angle in radians). return: - type: 'Num' + type: 'Float' description: > The cosine of `x`. args: x: - type: 'Num' + type: 'Float' description: > The angle in radians. example: | assert (0.0).cos() == 1 -Num.cosh: +Float.cosh: short: hyperbolic cosine description: > Computes the hyperbolic cosine of a number. return: - type: 'Num' + type: 'Float' description: > The hyperbolic cosine of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the hyperbolic cosine is to be calculated. example: | assert (0.0).cosh() == 1 -Num.erf: +Float.erf: short: error function description: > Computes the error function of a number. return: - type: 'Num' + type: 'Float' description: > The error function of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the error function is to be calculated. example: | assert (0.0).erf() == 0 -Num.erfc: +Float.erfc: short: complimentary error function description: > Computes the complementary error function of a number. return: - type: 'Num' + type: 'Float' description: > The complementary error function of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the complementary error function is to be calculated. example: | assert (0.0).erfc() == 1 -Num.exp: +Float.exp: short: base-e exponentiation description: > Computes the exponential function $e^x$ for a number. return: - type: 'Num' + type: 'Float' description: > The value of $e^x$. args: x: - type: 'Num' + type: 'Float' description: > The exponent. example: | assert (1.0).exp() == 2.7183 -Num.exp2: +Float.exp2: short: base-2 exponentiation description: > Computes $2^x$ for a number. return: - type: 'Num' + type: 'Float' description: > The value of $2^x$. args: x: - type: 'Num' + type: 'Float' description: > The exponent. example: | assert (3.0).exp2() == 8 -Num.expm1: +Float.expm1: short: base-e exponential minus 1 description: > Computes $e^x - 1$ for a number. return: - type: 'Num' + type: 'Float' description: > The value of $e^x - 1$. args: x: - type: 'Num' + type: 'Float' description: > The exponent. example: | assert (1.0).expm1() == 1.7183 -Num.fdim: +Float.fdim: short: positive difference description: > Computes the positive difference between two numbers. return: - type: 'Num' + type: 'Float' description: > The positive difference $\max(0, x - y)$. args: x: - type: 'Num' + type: 'Float' description: > The first number. y: - type: 'Num' + type: 'Float' description: > The second number. example: | @@ -341,43 +341,43 @@ Num.fdim: assert (5.0).fdim(3) == 2 -Num.floor: +Float.floor: short: floor function description: > Rounds a number down to the nearest integer. return: - type: 'Num' + type: 'Float' description: > The largest integer less than or equal to `x`. args: x: - type: 'Num' + type: 'Float' description: > The number to be rounded down. example: | assert (3.7).floor() == 3 -Num.hypot: +Float.hypot: short: Euclidean distance function description: > Computes the Euclidean norm, $\sqrt{x^2 + y^2}$, of two numbers. return: - type: 'Num' + type: 'Float' description: > The Euclidean norm of `x` and `y`. args: x: - type: 'Num' + type: 'Float' description: > The first number. y: - type: 'Num' + type: 'Float' description: > The second number. example: | - assert Num.hypot(3, 4) == 5 + assert Float.hypot(3, 4) == 5 -Num.isfinite: +Float.isfinite: short: check for finite number description: > Checks if a number is finite. @@ -387,14 +387,14 @@ Num.isfinite: `yes` if `n` is finite, `no` otherwise. args: n: - type: 'Num' + type: 'Float' description: > The number to be checked. example: | assert (1.0).isfinite() == yes - assert Num.INF.isfinite() == no + assert Float.INF.isfinite() == no -Num.is_between: +Float.is_between: short: check if a number is in a range description: > Determines if a number is between two numbers (inclusive). @@ -404,15 +404,15 @@ Num.is_between: `yes` if `a <= x and x <= b` or `b <= x and x <= a`, otherwise `no` args: x: - type: 'Num' + type: 'Float' description: > The integer to be checked. low: - type: 'Num' + type: 'Float' description: > One end of the range to check (inclusive). high: - type: 'Num' + type: 'Float' description: > The other end of the range to check (inclusive). example: | @@ -421,7 +421,7 @@ Num.is_between: assert (7.5).is_between(100, 200) == no assert (7.5).is_between(1, 7.5) == yes -Num.isinf: +Float.isinf: short: check for infinite number description: > Checks if a number is infinite. @@ -431,151 +431,151 @@ Num.isinf: `yes` if `n` is infinite, `no` otherwise. args: n: - type: 'Num' + type: 'Float' description: > The number to be checked. example: | - assert Num.INF.isinf() == yes + assert Float.INF.isinf() == yes assert (1.0).isinf() == no -Num.j0: +Float.j0: short: Bessel function description: > Computes the Bessel function of the first kind of order 0. return: - type: 'Num' + type: 'Float' description: > The Bessel function of the first kind of order 0 of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the Bessel function is to be calculated. example: | assert (0.0).j0() == 1 -Num.j1: +Float.j1: short: Bessel function description: > Computes the Bessel function of the first kind of order 1. return: - type: 'Num' + type: 'Float' description: > The Bessel function of the first kind of order 1 of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the Bessel function is to be calculated. example: | assert (0.0).j1() == 0 -Num.log: +Float.log: short: natural logarithm description: > Computes the natural logarithm (base $e$) of a number. return: - type: 'Num' + type: 'Float' description: > The natural logarithm of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the natural logarithm is to be calculated. example: | - assert Num.E.log() == 1 + assert Float.E.log() == 1 -Num.log10: +Float.log10: short: logarithm base-10 description: > Computes the base-10 logarithm of a number. return: - type: 'Num' + type: 'Float' description: > The base-10 logarithm of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the base-10 logarithm is to be calculated. example: | assert (100.0).log10() == 2 -Num.log1p: +Float.log1p: short: logarithm of 1 plus x description: > Computes $\log(1 + x)$ for a number. return: - type: 'Num' + type: 'Float' description: > The value of $\log(1 + x)$. args: x: - type: 'Num' + type: 'Float' description: > The number for which $\log(1 + x)$ is to be calculated. example: | assert (1.0).log1p() == 0.6931 -Num.log2: +Float.log2: short: logarithm base-2 description: > Computes the base-2 logarithm of a number. return: - type: 'Num' + type: 'Float' description: > The base-2 logarithm of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the base-2 logarithm is to be calculated. example: | assert (8.0).log2() == 3 -Num.logb: +Float.logb: short: exponent of a floating point value description: > Computes the binary exponent (base-2 logarithm) of a number. return: - type: 'Num' + type: 'Float' description: > The binary exponent of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the binary exponent is to be calculated. example: | assert (8.0).logb() == 3 -Num.mix: +Float.mix: short: mix two numbers by an amount description: > Interpolates between two numbers based on a given amount. return: - type: 'Num' + type: 'Float' description: > The interpolated number between `x` and `y` based on `amount`. args: amount: - type: 'Num' + type: 'Float' description: > The interpolation factor (between `0` and `1`). x: - type: 'Num' + type: 'Float' description: > The starting number. y: - type: 'Num' + type: 'Float' description: > The ending number. example: | assert (0.5).mix(10, 20) == 15 assert (0.25).mix(10, 20) == 12.5 -Num.near: +Float.near: short: check if two numbers are near each other description: > Checks if two numbers are approximately equal within specified tolerances. If @@ -587,20 +587,20 @@ Num.near: `yes` if `x` and `y` are approximately equal within the specified tolerances, `no` otherwise. args: x: - type: 'Num' + type: 'Float' description: > The first number. y: - type: 'Num' + type: 'Float' description: > The second number. ratio: - type: 'Num' + type: 'Float' default: '1e-9' description: > The relative tolerance. Default is `1e-9`. min_epsilon: - type: 'Num' + type: 'Float' default: '1e-9' description: > The absolute tolerance. Default is `1e-9`. @@ -609,32 +609,32 @@ Num.near: assert (100.0).near(110, ratio=0.1) == yes assert (5.0).near(5.1, min_epsilon=0.1) == yes -Num.nextafter: +Float.nextafter: short: next floating point number description: > Computes the next representable value after a given number towards a specified direction. return: - type: 'Num' + type: 'Float' description: > The next representable value after `x` in the direction of `y`. args: x: - type: 'Num' + type: 'Float' description: > The starting number. y: - type: 'Num' + type: 'Float' description: > The direction towards which to find the next representable value. example: | assert (1.0).nextafter(1.1) == 1.0000000000000002 -Num.parse: +Float.parse: short: convert text to number description: > Converts a text representation of a number into a floating-point number. return: - type: 'Num?' + type: 'Float?' description: > The number represented by the text or `none` if the entire text can't be parsed as a number. @@ -650,14 +650,14 @@ Num.parse: If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. example: | - assert Num.parse("3.14") == 3.14 - assert Num.parse("1e3") == 1000 - assert Num.parse("1.5junk") == none + assert Float.parse("3.14") == 3.14 + assert Float.parse("1e3") == 1000 + assert Float.parse("1.5junk") == none remainder : Text - assert Num.parse("1.5junk", &remainder) == 1.5 + assert Float.parse("1.5junk", &remainder) == 1.5 assert remainder == "junk" -Num.percent: +Float.percent: short: format as a percentage description: > Convert a number into a percentage text with a percent sign. @@ -667,11 +667,11 @@ Num.percent: A text representation of the number as a percentage with a percent sign. args: n: - type: 'Num' + type: 'Float' description: > The number to be converted to a percent. precision: - type: 'Num' + type: 'Float' default: '0.01' description: > Round the percentage to this precision level. @@ -681,21 +681,21 @@ Num.percent: assert (1./3.).percent(2, precision=0.0001) == "33.3333%" assert (1./3.).percent(2, precision=10.) == "30%" -Num.with_precision: +Float.with_precision: short: round to a given precision description: > Round a number to the given precision level (specified as `10`, `.1`, `.001` etc). return: - type: 'Num' + type: 'Float' description: > The number, rounded to the given precision level. args: n: - type: 'Num' + type: 'Float' description: > The number to be rounded to a given precision. precision: - type: 'Num' + type: 'Float' description: > The precision to which the number should be rounded. example: | @@ -703,269 +703,269 @@ Num.with_precision: assert (123456.).with_precision(100) == 123500 assert (1234567.).with_precision(5) == 1234565 -Num.rint: +Float.rint: short: round to nearest integer description: > Rounds a number to the nearest integer, with ties rounded to the nearest even integer. return: - type: 'Num' + type: 'Float' description: > The nearest integer value of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number to be rounded. example: | assert (3.5).rint() == 4 assert (2.5).rint() == 2 -Num.round: +Float.round: short: round to nearest integer description: > Rounds a number to the nearest whole number integer. return: - type: 'Num' + type: 'Float' description: > The nearest integer value of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number to be rounded. example: | assert (2.3).round() == 2 assert (2.7).round() == 3 -Num.significand: +Float.significand: short: get mantissa description: > Extracts the significand (or mantissa) of a number. return: - type: 'Num' + type: 'Float' description: > The significand of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number from which to extract the significand. example: | assert (1234.567).significand() == 0.1234567 -Num.sin: +Float.sin: short: sine description: > Computes the sine of a number (angle in radians). return: - type: 'Num' + type: 'Float' description: > The sine of `x`. args: x: - type: 'Num' + type: 'Float' description: > The angle in radians. example: | assert (0.0).sin() == 0 -Num.sinh: +Float.sinh: short: hyperbolic sine description: > Computes the hyperbolic sine of a number. return: - type: 'Num' + type: 'Float' description: > The hyperbolic sine of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the hyperbolic sine is to be calculated. example: | assert (0.0).sinh() == 0 -Num.sqrt: +Float.sqrt: short: square root description: > Computes the square root of a number. return: - type: 'Num' + type: 'Float' description: > The square root of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the square root is to be calculated. example: | assert (16.0).sqrt() == 4 -Num.tan: +Float.tan: short: tangent description: > Computes the tangent of a number (angle in radians). return: - type: 'Num' + type: 'Float' description: > The tangent of `x`. args: x: - type: 'Num' + type: 'Float' description: > The angle in radians. example: | assert (0.0).tan() == 0 -Num.tanh: +Float.tanh: short: hyperbolic tangent description: > Computes the hyperbolic tangent of a number. return: - type: 'Num' + type: 'Float' description: > The hyperbolic tangent of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the hyperbolic tangent is to be calculated. example: | assert (0.0).tanh() == 0 -Num.tgamma: +Float.tgamma: short: "true gamma function" description: > Computes the gamma function of a number. return: - type: 'Num' + type: 'Float' description: > The gamma function of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the gamma function is to be calculated. example: | assert (1.0).tgamma() == 1 -Num.trunc: +Float.trunc: short: truncate a number description: > Truncates a number to the nearest integer towards zero. return: - type: 'Num' + type: 'Float' description: > The integer part of `x` towards zero. args: x: - type: 'Num' + type: 'Float' description: > The number to be truncated. example: | assert (3.7).trunc() == 3 assert (-3.7).trunc() == -3 -Num.y0: +Float.y0: short: Bessel function description: > Computes the Bessel function of the second kind of order 0. return: - type: 'Num' + type: 'Float' description: > The Bessel function of the second kind of order 0 of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the Bessel function is to be calculated. example: | assert (1.0).y0() == -0.7652 -Num.y1: +Float.y1: short: Bessel function description: > Computes the Bessel function of the second kind of order 1. return: - type: 'Num' + type: 'Float' description: > The Bessel function of the second kind of order 1 of `x`. args: x: - type: 'Num' + type: 'Float' description: > The number for which the Bessel function is to be calculated. example: | assert (1.0).y1() == 0.4401 -Num.1_PI: +Float.1_PI: short: 1/pi - type: Num + type: Float description: > The constant $\frac{1}{\pi}$. -Num.2_PI: +Float.2_PI: short: 2*pi - type: Num + type: Float description: > The constant $2 \times \pi$. -Num.2_SQRTPI: +Float.2_SQRTPI: short: 2*sqrt(pi) - type: Num + type: Float description: > The constant $2 \times \sqrt{\pi}$. -Num.E: +Float.E: short: Euler's constant - type: Num + type: Float description: > The base of the natural logarithm ($e$). -Num.INF: +Float.INF: short: infinity - type: Num + type: Float description: > Positive infinity. -Num.LN10: +Float.LN10: short: log(10) - type: Num + type: Float description: > The natural logarithm of 10. -Num.LN2: +Float.LN2: short: log(2) - type: Num + type: Float description: > The natural logarithm of 2. -Num.LOG2E: +Float.LOG2E: short: log_2(e) - type: Num + type: Float description: > The base 2 logarithm of $e$ -Num.PI: +Float.PI: short: pi - type: Num + type: Float description: > Pi ($\pi$). -Num.PI_2: +Float.PI_2: short: pi/2 - type: Num + type: Float description: > $\frac{\pi}{2}$ -Num.PI_4: +Float.PI_4: short: pi/4 - type: Num + type: Float description: > $\frac{\pi}{4}$ -Num.SQRT1_2: +Float.SQRT1_2: short: sqrt(1/2) - type: Num + type: Float description: > $\sqrt{\frac{1}{2}}$ -Num.SQRT2: +Float.SQRT2: short: sqrt(2) - type: Num + type: Float description: > $\sqrt{2}$ -Num.TAU: +Float.TAU: short: 2*pi - type: Num + type: Float description: > Tau ($2 \times \pi$) diff --git a/api/lists.md b/api/lists.md index 1c741989..4d184830 100644 --- a/api/lists.md +++ b/api/lists.md @@ -407,7 +407,7 @@ assert [10, 20, 30].reversed() == [30, 20, 10] ## List.sample ```tomo -List.sample : func(list: [T], count: Int, weights: [Num]? = none, random: func(->Num)? = none -> [T]) +List.sample : func(list: [T], count: Int, weights: [Float64]? = none, random: func(->Float64)? = none -> [T]) ``` Selects a sample of elements from the list, optionally with weighted probabilities. @@ -418,8 +418,8 @@ Argument | Type | Description | Default ---------|------|-------------|--------- list | `[T]` | The list to sample from. | - count | `Int` | The number of elements to sample. | - -weights | `[Num]?` | The probability weights for each element in the list. These values do not need to add up to any particular number, they are relative weights. If no weights are given, elements will be sampled with uniform probability. | `none` -random | `func(->Num)?` | If provided, this function will be used to get random values for sampling the list. The provided function should return random numbers between `0.0` (inclusive) and `1.0` (exclusive). (Used for deterministic pseudorandom number generation) | `none` +weights | `[Float64]?` | The probability weights for each element in the list. These values do not need to add up to any particular number, they are relative weights. If no weights are given, elements will be sampled with uniform probability. | `none` +random | `func(->Float64)?` | If provided, this function will be used to get random values for sampling the list. The provided function should return random numbers between `0.0` (inclusive) and `1.0` (exclusive). (Used for deterministic pseudorandom number generation) | `none` **Return:** A list of sampled elements from the list. diff --git a/api/lists.yaml b/api/lists.yaml index 5a2bc2a1..ef526a9d 100644 --- a/api/lists.yaml +++ b/api/lists.yaml @@ -442,7 +442,7 @@ List.sample: description: > The number of elements to sample. weights: - type: '[Num]?' + type: '[Float64]?' default: 'none' description: > The probability weights for each element in the list. These @@ -450,7 +450,7 @@ List.sample: weights. If no weights are given, elements will be sampled with uniform probability. random: - type: 'func(->Num)?' + type: 'func(->Float64)?' default: 'none' description: > If provided, this function will be used to get random values for diff --git a/docs/functions.md b/docs/functions.md index 0b836bcc..11e1ea63 100644 --- a/docs/functions.md +++ b/docs/functions.md @@ -45,7 +45,7 @@ and are bound to arguments first, followed by binding positional arguments to any unbound arguments, in order: ```tomo -func foo(x:Int, y:Text, z:Num) +func foo(x:Int, y:Text, z:Float64) return "x=$x y=$y z=$z" func main() diff --git a/docs/nums.md b/docs/nums.md index 7502d8bc..4cd24c76 100644 --- a/docs/nums.md +++ b/docs/nums.md @@ -1,7 +1,7 @@ # Nums -Tomo has two floating point number types: `Num` (64-bit, AKA `double`) and -`Num32` (32-bit, AKA `float`). Num literals can have a decimal point (e.g. +Tomo has two floating point number types: `Float64` (64-bit, AKA `double`) and +`Float32` (32-bit, AKA `float`). Float64 literals can have a decimal point (e.g. `5.`), a scientific notation suffix (e.g. `1e8`) or a percent sign. Numbers that end in a percent sign are divided by 100 at compile time (i.e. `5% == 0.05`). Numbers can also use the `deg` suffix to represent degrees, which @@ -10,7 +10,7 @@ are converted to radians at compile time (i.e. `180deg == Nums.PI`). Nums support the standard math operations (`x+y`, `x-y`, `x*y`, `x/y`) as well as powers/exponentiation (`x^y`) and modulus (`x mod y` and `x mod1 y`). -32-bit numbers can be constructed using the type name: `Num32(123.456)`. +32-bit numbers can be constructed using the type name: `Float32(123.456)`. ## NaN @@ -26,11 +26,11 @@ differentiate between possibly-NaN values and definitely-not-NaN values. Tomo has a separate concept for expressing the lack of a defined value: optional types. Consequently, Tomo has merged these two concepts, so `NaN` is -called `none` and has the type `Num?` or `Num32?`. In this way, it's no +called `none` and has the type `Float64?` or `Float32?`. In this way, it's no different from optional integers or optional lists. This means that if a -variable has type `Num`, it is guaranteed to not hold a NaN value. This also +variable has type `Float64`, it is guaranteed to not hold a NaN value. This also means that operations which may produce NaN values have a result type of -`Num?`. For example, division can take two non-NaN values and return a result +`Float64?`. For example, division can take two non-NaN values and return a result that is NaN (zero divided by zero). Similarly, multiplication can produce NaN values (zero times infinity), and many math functions like `sqrt()` can return NaN for some inputs. @@ -65,7 +65,7 @@ assert (zero/y)! == 0 # implicit `!`: zero = zero/y -func doop(x:Num -> Num) +func doop(x:Float64 -> Float64) # If a function's return type is non-optional and an optional value is # used in a return statement, an implicit none check will be inserted and # will error if the value is none: diff --git a/docs/optionals.md b/docs/optionals.md index 326d77b5..a6d6c338 100644 --- a/docs/optionals.md +++ b/docs/optionals.md @@ -117,7 +117,7 @@ negative length for lists. However, for fixed-size integers (`Int64`, `Int32`, `Int16`, and `Int8`), bytes, and structs, an additional byte is required for out-of-band information about whether the value is none or not. -Floating point numbers (`Num` and `Num32`) use `NaN` to represent none, so +Floating point numbers (`Float64` and `Float32`) use `NaN` to represent none, so optional nums should be careful to avoid using `NaN` as a non-none value. This option was chosen to minimize the memory overhead of optional nums and because `NaN` literally means "not a number". diff --git a/examples/learnxiny.tm b/examples/learnxiny.tm index 6971f2a9..07b9e051 100644 --- a/examples/learnxiny.tm +++ b/examples/learnxiny.tm @@ -201,7 +201,7 @@ func demo_keyword_args() func takes_many_types( boolean:Bool, integer:Int, - floating_point_number:Num, + floating_point_number:Float64, text_aka_string:Text, list_of_ints:[Int], table_of_text_to_bools:{Text=Bool}, @@ -259,18 +259,18 @@ func demo_structs() # indicates which type it is, and any data you want to associate with it. enum Shape( Point, - Circle(radius:Num), - Rectangle(width:Num, height:Num), + Circle(radius:Float64), + Rectangle(width:Float64, height:Float64), ) # Just like with structs, you define methods and constants inside a level # of indentation: - func get_area(self:Shape->Num) + func get_area(self:Shape->Float64) # In order to work with an enum, it's most often handy to use a 'when' # statement to get the internal values: when self is Point return 0 is Circle(r) - return Num.PI * r^2 + return Float64.PI * r^2 is Rectangle(w, h) return w * h # 'when' statements are checked for exhaustiveness, so the compiler diff --git a/man/man3/tomo-Num.1_PI.3 b/man/man3/tomo-Float.1_PI.3 index 75245ad4..924e676d 100644 --- a/man/man3/tomo-Num.1_PI.3 +++ b/man/man3/tomo-Float.1_PI.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.1_PI 3 2025-11-29 "Tomo man-pages" +.TH Float.1_PI 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.1_PI \- 1/pi +Float.1_PI \- 1/pi .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.1_PI\ :\ Num +.BI Float.1_PI\ :\ Float .fi .SH DESCRIPTION The constant $\frac{1}{\pi}$. .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.2_PI.3 b/man/man3/tomo-Float.2_PI.3 index 9ea37335..aebce5eb 100644 --- a/man/man3/tomo-Num.2_PI.3 +++ b/man/man3/tomo-Float.2_PI.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.2_PI 3 2025-11-29 "Tomo man-pages" +.TH Float.2_PI 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.2_PI \- 2*pi +Float.2_PI \- 2*pi .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.2_PI\ :\ Num +.BI Float.2_PI\ :\ Float .fi .SH DESCRIPTION The constant $2 \times \pi$. .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.2_SQRTPI.3 b/man/man3/tomo-Float.2_SQRTPI.3 index aab8577a..7784602b 100644 --- a/man/man3/tomo-Num.2_SQRTPI.3 +++ b/man/man3/tomo-Float.2_SQRTPI.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.2_SQRTPI 3 2025-11-29 "Tomo man-pages" +.TH Float.2_SQRTPI 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.2_SQRTPI \- 2*sqrt(pi) +Float.2_SQRTPI \- 2*sqrt(pi) .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.2_SQRTPI\ :\ Num +.BI Float.2_SQRTPI\ :\ Float .fi .SH DESCRIPTION The constant $2 \times \sqrt{\pi}$. .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.3 b/man/man3/tomo-Float.3 index 99c9e8d5..e58ea7a7 100644 --- a/man/man3/tomo-Num.3 +++ b/man/man3/tomo-Float.3 @@ -2,522 +2,522 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num 3 2025-11-29 "Tomo man-pages" +.TH Float 3 2025-12-11 "Tomo man-pages" .SH NAME -Num \- a Tomo type +Float \- a Tomo type .SH LIBRARY Tomo Standard Library .fi .SH METHODS .TP -.BI Num.1_PI\ :\ Num +.BI Float.1_PI\ :\ Float The constant $\frac{1}{\pi}$. For more, see: -.BR Tomo-Num.1_PI (3) +.BR Tomo-Float.1_PI (3) .TP -.BI Num.2_PI\ :\ Num +.BI Float.2_PI\ :\ Float The constant $2 \times \pi$. For more, see: -.BR Tomo-Num.2_PI (3) +.BR Tomo-Float.2_PI (3) .TP -.BI Num.2_SQRTPI\ :\ Num +.BI Float.2_SQRTPI\ :\ Float The constant $2 \times \sqrt{\pi}$. For more, see: -.BR Tomo-Num.2_SQRTPI (3) +.BR Tomo-Float.2_SQRTPI (3) .TP -.BI Num.E\ :\ Num +.BI Float.E\ :\ Float The base of the natural logarithm ($e$). For more, see: -.BR Tomo-Num.E (3) +.BR Tomo-Float.E (3) .TP -.BI Num.INF\ :\ Num +.BI Float.INF\ :\ Float Positive infinity. For more, see: -.BR Tomo-Num.INF (3) +.BR Tomo-Float.INF (3) .TP -.BI Num.LN10\ :\ Num +.BI Float.LN10\ :\ Float The natural logarithm of 10. For more, see: -.BR Tomo-Num.LN10 (3) +.BR Tomo-Float.LN10 (3) .TP -.BI Num.LN2\ :\ Num +.BI Float.LN2\ :\ Float The natural logarithm of 2. For more, see: -.BR Tomo-Num.LN2 (3) +.BR Tomo-Float.LN2 (3) .TP -.BI Num.LOG2E\ :\ Num +.BI Float.LOG2E\ :\ Float The base 2 logarithm of $e$ For more, see: -.BR Tomo-Num.LOG2E (3) +.BR Tomo-Float.LOG2E (3) .TP -.BI Num.PI\ :\ Num +.BI Float.PI\ :\ Float Pi ($\pi$). For more, see: -.BR Tomo-Num.PI (3) +.BR Tomo-Float.PI (3) .TP -.BI Num.PI_2\ :\ Num +.BI Float.PI_2\ :\ Float $\frac{\pi}{2}$ For more, see: -.BR Tomo-Num.PI_2 (3) +.BR Tomo-Float.PI_2 (3) .TP -.BI Num.PI_4\ :\ Num +.BI Float.PI_4\ :\ Float $\frac{\pi}{4}$ For more, see: -.BR Tomo-Num.PI_4 (3) +.BR Tomo-Float.PI_4 (3) .TP -.BI Num.SQRT1_2\ :\ Num +.BI Float.SQRT1_2\ :\ Float $\sqrt{\frac{1}{2}}$ For more, see: -.BR Tomo-Num.SQRT1_2 (3) +.BR Tomo-Float.SQRT1_2 (3) .TP -.BI Num.SQRT2\ :\ Num +.BI Float.SQRT2\ :\ Float $\sqrt{2}$ For more, see: -.BR Tomo-Num.SQRT2 (3) +.BR Tomo-Float.SQRT2 (3) .TP -.BI Num.TAU\ :\ Num +.BI Float.TAU\ :\ Float Tau ($2 \times \pi$) For more, see: -.BR Tomo-Num.TAU (3) +.BR Tomo-Float.TAU (3) .TP -.BI Num.abs\ :\ func(n:\ Num\ ->\ Num) +.BI Float.abs\ :\ func(n:\ Float\ ->\ Float) Calculates the absolute value of a number. For more, see: -.BR Tomo-Num.abs (3) +.BR Tomo-Float.abs (3) .TP -.BI Num.acos\ :\ func(x:\ Num\ ->\ Num) +.BI Float.acos\ :\ func(x:\ Float\ ->\ Float) Computes the arc cosine of a number. For more, see: -.BR Tomo-Num.acos (3) +.BR Tomo-Float.acos (3) .TP -.BI Num.acosh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.acosh\ :\ func(x:\ Float\ ->\ Float) Computes the inverse hyperbolic cosine of a number. For more, see: -.BR Tomo-Num.acosh (3) +.BR Tomo-Float.acosh (3) .TP -.BI Num.asin\ :\ func(x:\ Num\ ->\ Num) +.BI Float.asin\ :\ func(x:\ Float\ ->\ Float) Computes the arc sine of a number. For more, see: -.BR Tomo-Num.asin (3) +.BR Tomo-Float.asin (3) .TP -.BI Num.asinh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.asinh\ :\ func(x:\ Float\ ->\ Float) Computes the inverse hyperbolic sine of a number. For more, see: -.BR Tomo-Num.asinh (3) +.BR Tomo-Float.asinh (3) .TP -.BI Num.atan\ :\ func(x:\ Num\ ->\ Num) +.BI Float.atan\ :\ func(x:\ Float\ ->\ Float) Computes the arc tangent of a number. For more, see: -.BR Tomo-Num.atan (3) +.BR Tomo-Float.atan (3) .TP -.BI Num.atan2\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.atan2\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) Computes the arc tangent of the quotient of two numbers. For more, see: -.BR Tomo-Num.atan2 (3) +.BR Tomo-Float.atan2 (3) .TP -.BI Num.atanh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.atanh\ :\ func(x:\ Float\ ->\ Float) Computes the inverse hyperbolic tangent of a number. For more, see: -.BR Tomo-Num.atanh (3) +.BR Tomo-Float.atanh (3) .TP -.BI Num.cbrt\ :\ func(x:\ Num\ ->\ Num) +.BI Float.cbrt\ :\ func(x:\ Float\ ->\ Float) Computes the cube root of a number. For more, see: -.BR Tomo-Num.cbrt (3) +.BR Tomo-Float.cbrt (3) .TP -.BI Num.ceil\ :\ func(x:\ Num\ ->\ Num) +.BI Float.ceil\ :\ func(x:\ Float\ ->\ Float) Rounds a number up to the nearest integer. For more, see: -.BR Tomo-Num.ceil (3) +.BR Tomo-Float.ceil (3) .TP -.BI Num.clamped\ :\ func(x:\ Num,\ low:\ Num,\ high:\ Num\ ->\ Num) +.BI Float.clamped\ :\ func(x:\ Float,\ low:\ Float,\ high:\ Float\ ->\ Float) Returns the given number clamped between two values so that it is within that range. For more, see: -.BR Tomo-Num.clamped (3) +.BR Tomo-Float.clamped (3) .TP -.BI Num.copysign\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.copysign\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) Copies the sign of one number to another. For more, see: -.BR Tomo-Num.copysign (3) +.BR Tomo-Float.copysign (3) .TP -.BI Num.cos\ :\ func(x:\ Num\ ->\ Num) +.BI Float.cos\ :\ func(x:\ Float\ ->\ Float) Computes the cosine of a number (angle in radians). For more, see: -.BR Tomo-Num.cos (3) +.BR Tomo-Float.cos (3) .TP -.BI Num.cosh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.cosh\ :\ func(x:\ Float\ ->\ Float) Computes the hyperbolic cosine of a number. For more, see: -.BR Tomo-Num.cosh (3) +.BR Tomo-Float.cosh (3) .TP -.BI Num.erf\ :\ func(x:\ Num\ ->\ Num) +.BI Float.erf\ :\ func(x:\ Float\ ->\ Float) Computes the error function of a number. For more, see: -.BR Tomo-Num.erf (3) +.BR Tomo-Float.erf (3) .TP -.BI Num.erfc\ :\ func(x:\ Num\ ->\ Num) +.BI Float.erfc\ :\ func(x:\ Float\ ->\ Float) Computes the complementary error function of a number. For more, see: -.BR Tomo-Num.erfc (3) +.BR Tomo-Float.erfc (3) .TP -.BI Num.exp\ :\ func(x:\ Num\ ->\ Num) +.BI Float.exp\ :\ func(x:\ Float\ ->\ Float) Computes the exponential function $e^x$ for a number. For more, see: -.BR Tomo-Num.exp (3) +.BR Tomo-Float.exp (3) .TP -.BI Num.exp2\ :\ func(x:\ Num\ ->\ Num) +.BI Float.exp2\ :\ func(x:\ Float\ ->\ Float) Computes $2^x$ for a number. For more, see: -.BR Tomo-Num.exp2 (3) +.BR Tomo-Float.exp2 (3) .TP -.BI Num.expm1\ :\ func(x:\ Num\ ->\ Num) +.BI Float.expm1\ :\ func(x:\ Float\ ->\ Float) Computes $e^x - 1$ for a number. For more, see: -.BR Tomo-Num.expm1 (3) +.BR Tomo-Float.expm1 (3) .TP -.BI Num.fdim\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.fdim\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) Computes the positive difference between two numbers. For more, see: -.BR Tomo-Num.fdim (3) +.BR Tomo-Float.fdim (3) .TP -.BI Num.floor\ :\ func(x:\ Num\ ->\ Num) +.BI Float.floor\ :\ func(x:\ Float\ ->\ Float) Rounds a number down to the nearest integer. For more, see: -.BR Tomo-Num.floor (3) +.BR Tomo-Float.floor (3) .TP -.BI Num.hypot\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.hypot\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) Computes the Euclidean norm, $\sqrt{x^2 + y^2}$, of two numbers. For more, see: -.BR Tomo-Num.hypot (3) +.BR Tomo-Float.hypot (3) .TP -.BI Num.is_between\ :\ func(x:\ Num,\ low:\ Num,\ high:\ Num\ ->\ Bool) +.BI Float.is_between\ :\ func(x:\ Float,\ low:\ Float,\ high:\ Float\ ->\ Bool) Determines if a number is between two numbers (inclusive). For more, see: -.BR Tomo-Num.is_between (3) +.BR Tomo-Float.is_between (3) .TP -.BI Num.isfinite\ :\ func(n:\ Num\ ->\ Bool) +.BI Float.isfinite\ :\ func(n:\ Float\ ->\ Bool) Checks if a number is finite. For more, see: -.BR Tomo-Num.isfinite (3) +.BR Tomo-Float.isfinite (3) .TP -.BI Num.isinf\ :\ func(n:\ Num\ ->\ Bool) +.BI Float.isinf\ :\ func(n:\ Float\ ->\ Bool) Checks if a number is infinite. For more, see: -.BR Tomo-Num.isinf (3) +.BR Tomo-Float.isinf (3) .TP -.BI Num.j0\ :\ func(x:\ Num\ ->\ Num) +.BI Float.j0\ :\ func(x:\ Float\ ->\ Float) Computes the Bessel function of the first kind of order 0. For more, see: -.BR Tomo-Num.j0 (3) +.BR Tomo-Float.j0 (3) .TP -.BI Num.j1\ :\ func(x:\ Num\ ->\ Num) +.BI Float.j1\ :\ func(x:\ Float\ ->\ Float) Computes the Bessel function of the first kind of order 1. For more, see: -.BR Tomo-Num.j1 (3) +.BR Tomo-Float.j1 (3) .TP -.BI Num.log\ :\ func(x:\ Num\ ->\ Num) +.BI Float.log\ :\ func(x:\ Float\ ->\ Float) Computes the natural logarithm (base $e$) of a number. For more, see: -.BR Tomo-Num.log (3) +.BR Tomo-Float.log (3) .TP -.BI Num.log10\ :\ func(x:\ Num\ ->\ Num) +.BI Float.log10\ :\ func(x:\ Float\ ->\ Float) Computes the base-10 logarithm of a number. For more, see: -.BR Tomo-Num.log10 (3) +.BR Tomo-Float.log10 (3) .TP -.BI Num.log1p\ :\ func(x:\ Num\ ->\ Num) +.BI Float.log1p\ :\ func(x:\ Float\ ->\ Float) Computes $\log(1 + x)$ for a number. For more, see: -.BR Tomo-Num.log1p (3) +.BR Tomo-Float.log1p (3) .TP -.BI Num.log2\ :\ func(x:\ Num\ ->\ Num) +.BI Float.log2\ :\ func(x:\ Float\ ->\ Float) Computes the base-2 logarithm of a number. For more, see: -.BR Tomo-Num.log2 (3) +.BR Tomo-Float.log2 (3) .TP -.BI Num.logb\ :\ func(x:\ Num\ ->\ Num) +.BI Float.logb\ :\ func(x:\ Float\ ->\ Float) Computes the binary exponent (base-2 logarithm) of a number. For more, see: -.BR Tomo-Num.logb (3) +.BR Tomo-Float.logb (3) .TP -.BI Num.mix\ :\ func(amount:\ Num,\ x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.mix\ :\ func(amount:\ Float,\ x:\ Float,\ y:\ Float\ ->\ Float) Interpolates between two numbers based on a given amount. For more, see: -.BR Tomo-Num.mix (3) +.BR Tomo-Float.mix (3) .TP -.BI Num.near\ :\ func(x:\ Num,\ y:\ Num,\ ratio:\ Num\ =\ 1e-9,\ min_epsilon:\ Num\ =\ 1e-9\ ->\ Bool) +.BI Float.near\ :\ func(x:\ Float,\ y:\ Float,\ ratio:\ Float\ =\ 1e-9,\ min_epsilon:\ Float\ =\ 1e-9\ ->\ Bool) Checks if two numbers are approximately equal within specified tolerances. If two numbers are within an absolute difference or the ratio between the two is small enough, they are considered near each other. For more, see: -.BR Tomo-Num.near (3) +.BR Tomo-Float.near (3) .TP -.BI Num.nextafter\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.nextafter\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) Computes the next representable value after a given number towards a specified direction. For more, see: -.BR Tomo-Num.nextafter (3) +.BR Tomo-Float.nextafter (3) .TP -.BI Num.parse\ :\ func(text:\ Text,\ remainder:\ &Text?\ =\ none\ ->\ Num?) +.BI Float.parse\ :\ func(text:\ Text,\ remainder:\ &Text?\ =\ none\ ->\ Float?) Converts a text representation of a number into a floating-point number. For more, see: -.BR Tomo-Num.parse (3) +.BR Tomo-Float.parse (3) .TP -.BI Num.percent\ :\ func(n:\ Num,\ precision:\ Num\ =\ 0.01\ ->\ Text) +.BI Float.percent\ :\ func(n:\ Float,\ precision:\ Float\ =\ 0.01\ ->\ Text) Convert a number into a percentage text with a percent sign. For more, see: -.BR Tomo-Num.percent (3) +.BR Tomo-Float.percent (3) .TP -.BI Num.rint\ :\ func(x:\ Num\ ->\ Num) +.BI Float.rint\ :\ func(x:\ Float\ ->\ Float) Rounds a number to the nearest integer, with ties rounded to the nearest even integer. For more, see: -.BR Tomo-Num.rint (3) +.BR Tomo-Float.rint (3) .TP -.BI Num.round\ :\ func(x:\ Num\ ->\ Num) +.BI Float.round\ :\ func(x:\ Float\ ->\ Float) Rounds a number to the nearest whole number integer. For more, see: -.BR Tomo-Num.round (3) +.BR Tomo-Float.round (3) .TP -.BI Num.significand\ :\ func(x:\ Num\ ->\ Num) +.BI Float.significand\ :\ func(x:\ Float\ ->\ Float) Extracts the significand (or mantissa) of a number. For more, see: -.BR Tomo-Num.significand (3) +.BR Tomo-Float.significand (3) .TP -.BI Num.sin\ :\ func(x:\ Num\ ->\ Num) +.BI Float.sin\ :\ func(x:\ Float\ ->\ Float) Computes the sine of a number (angle in radians). For more, see: -.BR Tomo-Num.sin (3) +.BR Tomo-Float.sin (3) .TP -.BI Num.sinh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.sinh\ :\ func(x:\ Float\ ->\ Float) Computes the hyperbolic sine of a number. For more, see: -.BR Tomo-Num.sinh (3) +.BR Tomo-Float.sinh (3) .TP -.BI Num.sqrt\ :\ func(x:\ Num\ ->\ Num) +.BI Float.sqrt\ :\ func(x:\ Float\ ->\ Float) Computes the square root of a number. For more, see: -.BR Tomo-Num.sqrt (3) +.BR Tomo-Float.sqrt (3) .TP -.BI Num.tan\ :\ func(x:\ Num\ ->\ Num) +.BI Float.tan\ :\ func(x:\ Float\ ->\ Float) Computes the tangent of a number (angle in radians). For more, see: -.BR Tomo-Num.tan (3) +.BR Tomo-Float.tan (3) .TP -.BI Num.tanh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.tanh\ :\ func(x:\ Float\ ->\ Float) Computes the hyperbolic tangent of a number. For more, see: -.BR Tomo-Num.tanh (3) +.BR Tomo-Float.tanh (3) .TP -.BI Num.tgamma\ :\ func(x:\ Num\ ->\ Num) +.BI Float.tgamma\ :\ func(x:\ Float\ ->\ Float) Computes the gamma function of a number. For more, see: -.BR Tomo-Num.tgamma (3) +.BR Tomo-Float.tgamma (3) .TP -.BI Num.trunc\ :\ func(x:\ Num\ ->\ Num) +.BI Float.trunc\ :\ func(x:\ Float\ ->\ Float) Truncates a number to the nearest integer towards zero. For more, see: -.BR Tomo-Num.trunc (3) +.BR Tomo-Float.trunc (3) .TP -.BI Num.with_precision\ :\ func(n:\ Num,\ precision:\ Num\ ->\ Num) +.BI Float.with_precision\ :\ func(n:\ Float,\ precision:\ Float\ ->\ Float) Round a number to the given precision level (specified as \fB10\fR, \fB.1\fR, \fB.001\fR etc). For more, see: -.BR Tomo-Num.with_precision (3) +.BR Tomo-Float.with_precision (3) .TP -.BI Num.y0\ :\ func(x:\ Num\ ->\ Num) +.BI Float.y0\ :\ func(x:\ Float\ ->\ Float) Computes the Bessel function of the second kind of order 0. For more, see: -.BR Tomo-Num.y0 (3) +.BR Tomo-Float.y0 (3) .TP -.BI Num.y1\ :\ func(x:\ Num\ ->\ Num) +.BI Float.y1\ :\ func(x:\ Float\ ->\ Float) Computes the Bessel function of the second kind of order 1. For more, see: -.BR Tomo-Num.y1 (3) +.BR Tomo-Float.y1 (3) diff --git a/man/man3/tomo-Num.E.3 b/man/man3/tomo-Float.E.3 index 771c015a..3bab1eb2 100644 --- a/man/man3/tomo-Num.E.3 +++ b/man/man3/tomo-Float.E.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.E 3 2025-11-29 "Tomo man-pages" +.TH Float.E 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.E \- Euler's constant +Float.E \- Euler's constant .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.E\ :\ Num +.BI Float.E\ :\ Float .fi .SH DESCRIPTION The base of the natural logarithm ($e$). .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.INF.3 b/man/man3/tomo-Float.INF.3 index 364274e2..a166f126 100644 --- a/man/man3/tomo-Num.INF.3 +++ b/man/man3/tomo-Float.INF.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.INF 3 2025-11-29 "Tomo man-pages" +.TH Float.INF 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.INF \- infinity +Float.INF \- infinity .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.INF\ :\ Num +.BI Float.INF\ :\ Float .fi .SH DESCRIPTION Positive infinity. .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.LN10.3 b/man/man3/tomo-Float.LN10.3 index 25c9ea99..98fb36ac 100644 --- a/man/man3/tomo-Num.LN10.3 +++ b/man/man3/tomo-Float.LN10.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.LN10 3 2025-11-29 "Tomo man-pages" +.TH Float.LN10 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.LN10 \- log(10) +Float.LN10 \- log(10) .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.LN10\ :\ Num +.BI Float.LN10\ :\ Float .fi .SH DESCRIPTION The natural logarithm of 10. .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.LN2.3 b/man/man3/tomo-Float.LN2.3 index e91741df..bbfd9381 100644 --- a/man/man3/tomo-Num.LN2.3 +++ b/man/man3/tomo-Float.LN2.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.LN2 3 2025-11-29 "Tomo man-pages" +.TH Float.LN2 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.LN2 \- log(2) +Float.LN2 \- log(2) .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.LN2\ :\ Num +.BI Float.LN2\ :\ Float .fi .SH DESCRIPTION The natural logarithm of 2. .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.LOG2E.3 b/man/man3/tomo-Float.LOG2E.3 index 35f8abc5..949b6db6 100644 --- a/man/man3/tomo-Num.LOG2E.3 +++ b/man/man3/tomo-Float.LOG2E.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.LOG2E 3 2025-11-29 "Tomo man-pages" +.TH Float.LOG2E 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.LOG2E \- log_2(e) +Float.LOG2E \- log_2(e) .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.LOG2E\ :\ Num +.BI Float.LOG2E\ :\ Float .fi .SH DESCRIPTION The base 2 logarithm of $e$ .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.PI.3 b/man/man3/tomo-Float.PI.3 index a3d3518a..3cfe28d6 100644 --- a/man/man3/tomo-Num.PI.3 +++ b/man/man3/tomo-Float.PI.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.PI 3 2025-11-29 "Tomo man-pages" +.TH Float.PI 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.PI \- pi +Float.PI \- pi .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.PI\ :\ Num +.BI Float.PI\ :\ Float .fi .SH DESCRIPTION Pi ($\pi$). .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.PI_2.3 b/man/man3/tomo-Float.PI_2.3 index 6801a71c..27e73490 100644 --- a/man/man3/tomo-Num.PI_2.3 +++ b/man/man3/tomo-Float.PI_2.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.PI_2 3 2025-11-29 "Tomo man-pages" +.TH Float.PI_2 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.PI_2 \- pi/2 +Float.PI_2 \- pi/2 .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.PI_2\ :\ Num +.BI Float.PI_2\ :\ Float .fi .SH DESCRIPTION $\frac{\pi}{2}$ .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.PI_4.3 b/man/man3/tomo-Float.PI_4.3 index e1a18648..96ef1c28 100644 --- a/man/man3/tomo-Num.PI_4.3 +++ b/man/man3/tomo-Float.PI_4.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.PI_4 3 2025-11-29 "Tomo man-pages" +.TH Float.PI_4 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.PI_4 \- pi/4 +Float.PI_4 \- pi/4 .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.PI_4\ :\ Num +.BI Float.PI_4\ :\ Float .fi .SH DESCRIPTION $\frac{\pi}{4}$ .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.SQRT1_2.3 b/man/man3/tomo-Float.SQRT1_2.3 index fc347716..a2d5a83b 100644 --- a/man/man3/tomo-Num.SQRT1_2.3 +++ b/man/man3/tomo-Float.SQRT1_2.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.SQRT1_2 3 2025-11-29 "Tomo man-pages" +.TH Float.SQRT1_2 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.SQRT1_2 \- sqrt(1/2) +Float.SQRT1_2 \- sqrt(1/2) .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.SQRT1_2\ :\ Num +.BI Float.SQRT1_2\ :\ Float .fi .SH DESCRIPTION $\sqrt{\frac{1}{2}}$ .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.SQRT2.3 b/man/man3/tomo-Float.SQRT2.3 index 5b3bf304..0a75b3ad 100644 --- a/man/man3/tomo-Num.SQRT2.3 +++ b/man/man3/tomo-Float.SQRT2.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.SQRT2 3 2025-11-29 "Tomo man-pages" +.TH Float.SQRT2 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.SQRT2 \- sqrt(2) +Float.SQRT2 \- sqrt(2) .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.SQRT2\ :\ Num +.BI Float.SQRT2\ :\ Float .fi .SH DESCRIPTION $\sqrt{2}$ .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.TAU.3 b/man/man3/tomo-Float.TAU.3 index 38d22030..3127cbc8 100644 --- a/man/man3/tomo-Num.TAU.3 +++ b/man/man3/tomo-Float.TAU.3 @@ -2,18 +2,18 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.TAU 3 2025-11-29 "Tomo man-pages" +.TH Float.TAU 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.TAU \- 2*pi +Float.TAU \- 2*pi .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.TAU\ :\ Num +.BI Float.TAU\ :\ Float .fi .SH DESCRIPTION Tau ($2 \times \pi$) .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.abs.3 b/man/man3/tomo-Float.abs.3 index 7bff8981..7e749008 100644 --- a/man/man3/tomo-Num.abs.3 +++ b/man/man3/tomo-Float.abs.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.abs 3 2025-11-29 "Tomo man-pages" +.TH Float.abs 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.abs \- absolute value +Float.abs \- absolute value .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.abs\ :\ func(n:\ Num\ ->\ Num) +.BI Float.abs\ :\ func(n:\ Float\ ->\ Float) .fi .SH DESCRIPTION Calculates the absolute value of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -n Num The number whose absolute value is to be computed. +n Float The number whose absolute value is to be computed. .TE .SH RETURN The absolute value of `n`. @@ -32,4 +32,4 @@ The absolute value of `n`. assert (-3.5).abs() == 3.5 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.acos.3 b/man/man3/tomo-Float.acos.3 index 83070c32..44733782 100644 --- a/man/man3/tomo-Num.acos.3 +++ b/man/man3/tomo-Float.acos.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.acos 3 2025-11-29 "Tomo man-pages" +.TH Float.acos 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.acos \- arc cosine +Float.acos \- arc cosine .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.acos\ :\ func(x:\ Num\ ->\ Num) +.BI Float.acos\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the arc cosine of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the arc cosine is to be calculated. +x Float The number for which the arc cosine is to be calculated. .TE .SH RETURN The arc cosine of `x` in radians. @@ -32,4 +32,4 @@ The arc cosine of `x` in radians. assert (0.0).acos() == 1.5708 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.acosh.3 b/man/man3/tomo-Float.acosh.3 index 680d6e24..f2f63f13 100644 --- a/man/man3/tomo-Num.acosh.3 +++ b/man/man3/tomo-Float.acosh.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.acosh 3 2025-11-29 "Tomo man-pages" +.TH Float.acosh 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.acosh \- arc hyperbolic cosine +Float.acosh \- arc hyperbolic cosine .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.acosh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.acosh\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the inverse hyperbolic cosine of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the inverse hyperbolic cosine is to be calculated. +x Float The number for which the inverse hyperbolic cosine is to be calculated. .TE .SH RETURN The inverse hyperbolic cosine of `x`. @@ -32,4 +32,4 @@ The inverse hyperbolic cosine of `x`. assert (1.0).acosh() == 0 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.asin.3 b/man/man3/tomo-Float.asin.3 index c44e5fe4..4ab9f0fa 100644 --- a/man/man3/tomo-Num.asin.3 +++ b/man/man3/tomo-Float.asin.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.asin 3 2025-11-29 "Tomo man-pages" +.TH Float.asin 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.asin \- arc sine +Float.asin \- arc sine .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.asin\ :\ func(x:\ Num\ ->\ Num) +.BI Float.asin\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the arc sine of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the arc sine is to be calculated. +x Float The number for which the arc sine is to be calculated. .TE .SH RETURN The arc sine of `x` in radians. @@ -32,4 +32,4 @@ The arc sine of `x` in radians. assert (0.5).asin() == 0.5236 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.asinh.3 b/man/man3/tomo-Float.asinh.3 index ac1fe25a..62436446 100644 --- a/man/man3/tomo-Num.asinh.3 +++ b/man/man3/tomo-Float.asinh.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.asinh 3 2025-11-29 "Tomo man-pages" +.TH Float.asinh 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.asinh \- arc hyperbolic sine +Float.asinh \- arc hyperbolic sine .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.asinh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.asinh\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the inverse hyperbolic sine of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the inverse hyperbolic sine is to be calculated. +x Float The number for which the inverse hyperbolic sine is to be calculated. .TE .SH RETURN The inverse hyperbolic sine of `x`. @@ -32,4 +32,4 @@ The inverse hyperbolic sine of `x`. assert (0.0).asinh() == 0 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.atan.3 b/man/man3/tomo-Float.atan.3 index e2303e64..22e28da7 100644 --- a/man/man3/tomo-Num.atan.3 +++ b/man/man3/tomo-Float.atan.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.atan 3 2025-11-29 "Tomo man-pages" +.TH Float.atan 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.atan \- arc tangent +Float.atan \- arc tangent .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.atan\ :\ func(x:\ Num\ ->\ Num) +.BI Float.atan\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the arc tangent of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the arc tangent is to be calculated. +x Float The number for which the arc tangent is to be calculated. .TE .SH RETURN The arc tangent of `x` in radians. @@ -32,4 +32,4 @@ The arc tangent of `x` in radians. assert (1.0).atan() == 0.7854 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.atan2.3 b/man/man3/tomo-Float.atan2.3 index aa9b2585..e92bec28 100644 --- a/man/man3/tomo-Num.atan2.3 +++ b/man/man3/tomo-Float.atan2.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.atan2 3 2025-11-29 "Tomo man-pages" +.TH Float.atan2 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.atan2 \- arc tangent from 2 variables +Float.atan2 \- arc tangent from 2 variables .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.atan2\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.atan2\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the arc tangent of the quotient of two numbers. @@ -22,15 +22,15 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The numerator. -y Num The denominator. +x Float The numerator. +y Float The denominator. .TE .SH RETURN The arc tangent of `x/y` in radians. .SH EXAMPLES .EX -assert Num.atan2(1, 1) == 0.7854 +assert Float.atan2(1, 1) == 0.7854 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.atanh.3 b/man/man3/tomo-Float.atanh.3 index 13e2ccb2..d32acdf9 100644 --- a/man/man3/tomo-Num.atanh.3 +++ b/man/man3/tomo-Float.atanh.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.atanh 3 2025-11-29 "Tomo man-pages" +.TH Float.atanh 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.atanh \- arc hyperbolic tangent. +Float.atanh \- arc hyperbolic tangent. .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.atanh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.atanh\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the inverse hyperbolic tangent of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the inverse hyperbolic tangent is to be calculated. +x Float The number for which the inverse hyperbolic tangent is to be calculated. .TE .SH RETURN The inverse hyperbolic tangent of `x`. @@ -32,4 +32,4 @@ The inverse hyperbolic tangent of `x`. assert (0.5).atanh() == 0.5493 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.cbrt.3 b/man/man3/tomo-Float.cbrt.3 index 790abf86..864a0a9e 100644 --- a/man/man3/tomo-Num.cbrt.3 +++ b/man/man3/tomo-Float.cbrt.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.cbrt 3 2025-11-29 "Tomo man-pages" +.TH Float.cbrt 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.cbrt \- cube root +Float.cbrt \- cube root .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.cbrt\ :\ func(x:\ Num\ ->\ Num) +.BI Float.cbrt\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the cube root of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the cube root is to be calculated. +x Float The number for which the cube root is to be calculated. .TE .SH RETURN The cube root of `x`. @@ -32,4 +32,4 @@ The cube root of `x`. assert (27.0).cbrt() == 3 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.ceil.3 b/man/man3/tomo-Float.ceil.3 index a43b0414..0386f50c 100644 --- a/man/man3/tomo-Num.ceil.3 +++ b/man/man3/tomo-Float.ceil.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.ceil 3 2025-11-29 "Tomo man-pages" +.TH Float.ceil 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.ceil \- ceiling function +Float.ceil \- ceiling function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.ceil\ :\ func(x:\ Num\ ->\ Num) +.BI Float.ceil\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Rounds a number up to the nearest integer. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number to be rounded up. +x Float The number to be rounded up. .TE .SH RETURN The smallest integer greater than or equal to `x`. @@ -32,4 +32,4 @@ The smallest integer greater than or equal to `x`. assert (3.2).ceil() == 4 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.clamped.3 b/man/man3/tomo-Float.clamped.3 index 21136b26..1d6998f8 100644 --- a/man/man3/tomo-Num.clamped.3 +++ b/man/man3/tomo-Float.clamped.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.clamped 3 2025-11-29 "Tomo man-pages" +.TH Float.clamped 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.clamped \- clamp a number +Float.clamped \- clamp a number .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.clamped\ :\ func(x:\ Num,\ low:\ Num,\ high:\ Num\ ->\ Num) +.BI Float.clamped\ :\ func(x:\ Float,\ low:\ Float,\ high:\ Float\ ->\ Float) .fi .SH DESCRIPTION Returns the given number clamped between two values so that it is within that range. @@ -22,9 +22,9 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number to clamp. -low Num The lowest value the result can take. -high Num The highest value the result can take. +x Float The number to clamp. +low Float The lowest value the result can take. +high Float The highest value the result can take. .TE .SH RETURN The first argument clamped between the other two arguments. @@ -34,4 +34,4 @@ The first argument clamped between the other two arguments. assert (2.5).clamped(5.5, 10.5) == 5.5 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.copysign.3 b/man/man3/tomo-Float.copysign.3 index 919772cd..2b75c782 100644 --- a/man/man3/tomo-Num.copysign.3 +++ b/man/man3/tomo-Float.copysign.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.copysign 3 2025-11-29 "Tomo man-pages" +.TH Float.copysign 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.copysign \- copy a number's sign +Float.copysign \- copy a number's sign .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.copysign\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.copysign\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) .fi .SH DESCRIPTION Copies the sign of one number to another. @@ -22,8 +22,8 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number whose magnitude will be copied. -y Num The number whose sign will be copied. +x Float The number whose magnitude will be copied. +y Float The number whose sign will be copied. .TE .SH RETURN A number with the magnitude of `x` and the sign of `y`. @@ -33,4 +33,4 @@ A number with the magnitude of `x` and the sign of `y`. assert (3.0).copysign(-1) == -3 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.cos.3 b/man/man3/tomo-Float.cos.3 index 0d4932d2..266dd5fd 100644 --- a/man/man3/tomo-Num.cos.3 +++ b/man/man3/tomo-Float.cos.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.cos 3 2025-11-29 "Tomo man-pages" +.TH Float.cos 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.cos \- cosine +Float.cos \- cosine .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.cos\ :\ func(x:\ Num\ ->\ Num) +.BI Float.cos\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the cosine of a number (angle in radians). @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The angle in radians. +x Float The angle in radians. .TE .SH RETURN The cosine of `x`. @@ -32,4 +32,4 @@ The cosine of `x`. assert (0.0).cos() == 1 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.cosh.3 b/man/man3/tomo-Float.cosh.3 index adc0bba5..5de41a15 100644 --- a/man/man3/tomo-Num.cosh.3 +++ b/man/man3/tomo-Float.cosh.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.cosh 3 2025-11-29 "Tomo man-pages" +.TH Float.cosh 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.cosh \- hyperbolic cosine +Float.cosh \- hyperbolic cosine .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.cosh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.cosh\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the hyperbolic cosine of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the hyperbolic cosine is to be calculated. +x Float The number for which the hyperbolic cosine is to be calculated. .TE .SH RETURN The hyperbolic cosine of `x`. @@ -32,4 +32,4 @@ The hyperbolic cosine of `x`. assert (0.0).cosh() == 1 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.erf.3 b/man/man3/tomo-Float.erf.3 index 8a2afed3..d356f844 100644 --- a/man/man3/tomo-Num.erf.3 +++ b/man/man3/tomo-Float.erf.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.erf 3 2025-11-29 "Tomo man-pages" +.TH Float.erf 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.erf \- error function +Float.erf \- error function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.erf\ :\ func(x:\ Num\ ->\ Num) +.BI Float.erf\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the error function of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the error function is to be calculated. +x Float The number for which the error function is to be calculated. .TE .SH RETURN The error function of `x`. @@ -32,4 +32,4 @@ The error function of `x`. assert (0.0).erf() == 0 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.erfc.3 b/man/man3/tomo-Float.erfc.3 index 82de219c..6ff7891b 100644 --- a/man/man3/tomo-Num.erfc.3 +++ b/man/man3/tomo-Float.erfc.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.erfc 3 2025-11-29 "Tomo man-pages" +.TH Float.erfc 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.erfc \- complimentary error function +Float.erfc \- complimentary error function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.erfc\ :\ func(x:\ Num\ ->\ Num) +.BI Float.erfc\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the complementary error function of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the complementary error function is to be calculated. +x Float The number for which the complementary error function is to be calculated. .TE .SH RETURN The complementary error function of `x`. @@ -32,4 +32,4 @@ The complementary error function of `x`. assert (0.0).erfc() == 1 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.exp.3 b/man/man3/tomo-Float.exp.3 index ac784957..e073e1ef 100644 --- a/man/man3/tomo-Num.exp.3 +++ b/man/man3/tomo-Float.exp.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.exp 3 2025-11-29 "Tomo man-pages" +.TH Float.exp 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.exp \- base-e exponentiation +Float.exp \- base-e exponentiation .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.exp\ :\ func(x:\ Num\ ->\ Num) +.BI Float.exp\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the exponential function $e^x$ for a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The exponent. +x Float The exponent. .TE .SH RETURN The value of $e^x$. @@ -32,4 +32,4 @@ The value of $e^x$. assert (1.0).exp() == 2.7183 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.exp2.3 b/man/man3/tomo-Float.exp2.3 index 194de5ce..b4dd35e2 100644 --- a/man/man3/tomo-Num.exp2.3 +++ b/man/man3/tomo-Float.exp2.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.exp2 3 2025-11-29 "Tomo man-pages" +.TH Float.exp2 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.exp2 \- base-2 exponentiation +Float.exp2 \- base-2 exponentiation .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.exp2\ :\ func(x:\ Num\ ->\ Num) +.BI Float.exp2\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes $2^x$ for a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The exponent. +x Float The exponent. .TE .SH RETURN The value of $2^x$. @@ -32,4 +32,4 @@ The value of $2^x$. assert (3.0).exp2() == 8 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.expm1.3 b/man/man3/tomo-Float.expm1.3 index 099186cc..5b4cf3df 100644 --- a/man/man3/tomo-Num.expm1.3 +++ b/man/man3/tomo-Float.expm1.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.expm1 3 2025-11-29 "Tomo man-pages" +.TH Float.expm1 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.expm1 \- base-e exponential minus 1 +Float.expm1 \- base-e exponential minus 1 .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.expm1\ :\ func(x:\ Num\ ->\ Num) +.BI Float.expm1\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes $e^x - 1$ for a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The exponent. +x Float The exponent. .TE .SH RETURN The value of $e^x - 1$. @@ -32,4 +32,4 @@ The value of $e^x - 1$. assert (1.0).expm1() == 1.7183 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.fdim.3 b/man/man3/tomo-Float.fdim.3 index 2b1071d1..a3be0af5 100644 --- a/man/man3/tomo-Num.fdim.3 +++ b/man/man3/tomo-Float.fdim.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.fdim 3 2025-11-29 "Tomo man-pages" +.TH Float.fdim 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.fdim \- positive difference +Float.fdim \- positive difference .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.fdim\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.fdim\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the positive difference between two numbers. @@ -22,8 +22,8 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The first number. -y Num The second number. +x Float The first number. +y Float The second number. .TE .SH RETURN The positive difference $\max(0, x - y)$. @@ -35,4 +35,4 @@ fd assert (5.0).fdim(3) == 2 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.floor.3 b/man/man3/tomo-Float.floor.3 index 5dfc2ae0..55f5924d 100644 --- a/man/man3/tomo-Num.floor.3 +++ b/man/man3/tomo-Float.floor.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.floor 3 2025-11-29 "Tomo man-pages" +.TH Float.floor 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.floor \- floor function +Float.floor \- floor function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.floor\ :\ func(x:\ Num\ ->\ Num) +.BI Float.floor\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Rounds a number down to the nearest integer. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number to be rounded down. +x Float The number to be rounded down. .TE .SH RETURN The largest integer less than or equal to `x`. @@ -32,4 +32,4 @@ The largest integer less than or equal to `x`. assert (3.7).floor() == 3 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.hypot.3 b/man/man3/tomo-Float.hypot.3 index 67bbd9af..3189de94 100644 --- a/man/man3/tomo-Num.hypot.3 +++ b/man/man3/tomo-Float.hypot.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.hypot 3 2025-11-29 "Tomo man-pages" +.TH Float.hypot 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.hypot \- Euclidean distance function +Float.hypot \- Euclidean distance function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.hypot\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.hypot\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the Euclidean norm, $\sqrt{x^2 + y^2}$, of two numbers. @@ -22,15 +22,15 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The first number. -y Num The second number. +x Float The first number. +y Float The second number. .TE .SH RETURN The Euclidean norm of `x` and `y`. .SH EXAMPLES .EX -assert Num.hypot(3, 4) == 5 +assert Float.hypot(3, 4) == 5 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.is_between.3 b/man/man3/tomo-Float.is_between.3 index ea78d895..a1ad3135 100644 --- a/man/man3/tomo-Num.is_between.3 +++ b/man/man3/tomo-Float.is_between.3 @@ -1,15 +1,15 @@ '\" t -.\" Copyright (c) 2025 Bruce Hill +.\" Copyright (c) 2026 Bruce Hill .\" All rights reserved. .\" -.TH Num.is_between 3 2025-12-31 "Tomo man-pages" +.TH Float.is_between 3 2026-01-02 "Tomo man-pages" .SH NAME -Num.is_between \- check if a number is in a range +Float.is_between \- check if a number is in a range .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.is_between\ :\ func(x:\ Num,\ low:\ Num,\ high:\ Num\ ->\ Bool) +.BI Float.is_between\ :\ func(x:\ Float,\ low:\ Float,\ high:\ Float\ ->\ Bool) .fi .SH DESCRIPTION Determines if a number is between two numbers (inclusive). @@ -22,9 +22,9 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The integer to be checked. -low Num One end of the range to check (inclusive). -high Num The other end of the range to check (inclusive). +x Float The integer to be checked. +low Float One end of the range to check (inclusive). +high Float The other end of the range to check (inclusive). .TE .SH RETURN `yes` if `a <= x and x <= b` or `b <= x and x <= a`, otherwise `no` @@ -37,4 +37,4 @@ assert (7.5).is_between(100, 200) == no assert (7.5).is_between(1, 7.5) == yes .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.isfinite.3 b/man/man3/tomo-Float.isfinite.3 index 81002b32..ee831f3d 100644 --- a/man/man3/tomo-Num.isfinite.3 +++ b/man/man3/tomo-Float.isfinite.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.isfinite 3 2025-11-29 "Tomo man-pages" +.TH Float.isfinite 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.isfinite \- check for finite number +Float.isfinite \- check for finite number .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.isfinite\ :\ func(n:\ Num\ ->\ Bool) +.BI Float.isfinite\ :\ func(n:\ Float\ ->\ Bool) .fi .SH DESCRIPTION Checks if a number is finite. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -n Num The number to be checked. +n Float The number to be checked. .TE .SH RETURN `yes` if `n` is finite, `no` otherwise. @@ -30,7 +30,7 @@ n Num The number to be checked. .SH EXAMPLES .EX assert (1.0).isfinite() == yes -assert Num.INF.isfinite() == no +assert Float.INF.isfinite() == no .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.isinf.3 b/man/man3/tomo-Float.isinf.3 index 33016ae8..8d4dfe7a 100644 --- a/man/man3/tomo-Num.isinf.3 +++ b/man/man3/tomo-Float.isinf.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.isinf 3 2025-11-29 "Tomo man-pages" +.TH Float.isinf 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.isinf \- check for infinite number +Float.isinf \- check for infinite number .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.isinf\ :\ func(n:\ Num\ ->\ Bool) +.BI Float.isinf\ :\ func(n:\ Float\ ->\ Bool) .fi .SH DESCRIPTION Checks if a number is infinite. @@ -22,15 +22,15 @@ allbox; lb lb lbx l l l. Name Type Description -n Num The number to be checked. +n Float The number to be checked. .TE .SH RETURN `yes` if `n` is infinite, `no` otherwise. .SH EXAMPLES .EX -assert Num.INF.isinf() == yes +assert Float.INF.isinf() == yes assert (1.0).isinf() == no .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.j0.3 b/man/man3/tomo-Float.j0.3 index a4847bec..f7570210 100644 --- a/man/man3/tomo-Num.j0.3 +++ b/man/man3/tomo-Float.j0.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.j0 3 2025-11-29 "Tomo man-pages" +.TH Float.j0 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.j0 \- Bessel function +Float.j0 \- Bessel function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.j0\ :\ func(x:\ Num\ ->\ Num) +.BI Float.j0\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the Bessel function of the first kind of order 0. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the Bessel function is to be calculated. +x Float The number for which the Bessel function is to be calculated. .TE .SH RETURN The Bessel function of the first kind of order 0 of `x`. @@ -32,4 +32,4 @@ The Bessel function of the first kind of order 0 of `x`. assert (0.0).j0() == 1 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.j1.3 b/man/man3/tomo-Float.j1.3 index eae8b9b7..17df3bd2 100644 --- a/man/man3/tomo-Num.j1.3 +++ b/man/man3/tomo-Float.j1.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.j1 3 2025-11-29 "Tomo man-pages" +.TH Float.j1 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.j1 \- Bessel function +Float.j1 \- Bessel function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.j1\ :\ func(x:\ Num\ ->\ Num) +.BI Float.j1\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the Bessel function of the first kind of order 1. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the Bessel function is to be calculated. +x Float The number for which the Bessel function is to be calculated. .TE .SH RETURN The Bessel function of the first kind of order 1 of `x`. @@ -32,4 +32,4 @@ The Bessel function of the first kind of order 1 of `x`. assert (0.0).j1() == 0 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.log.3 b/man/man3/tomo-Float.log.3 index 594e9edc..13360d0f 100644 --- a/man/man3/tomo-Num.log.3 +++ b/man/man3/tomo-Float.log.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.log 3 2025-11-29 "Tomo man-pages" +.TH Float.log 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.log \- natural logarithm +Float.log \- natural logarithm .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.log\ :\ func(x:\ Num\ ->\ Num) +.BI Float.log\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the natural logarithm (base $e$) of a number. @@ -22,14 +22,14 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the natural logarithm is to be calculated. +x Float The number for which the natural logarithm is to be calculated. .TE .SH RETURN The natural logarithm of `x`. .SH EXAMPLES .EX -assert Num.E.log() == 1 +assert Float.E.log() == 1 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.log10.3 b/man/man3/tomo-Float.log10.3 index 181b26f8..c50e0fb0 100644 --- a/man/man3/tomo-Num.log10.3 +++ b/man/man3/tomo-Float.log10.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.log10 3 2025-11-29 "Tomo man-pages" +.TH Float.log10 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.log10 \- logarithm base-10 +Float.log10 \- logarithm base-10 .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.log10\ :\ func(x:\ Num\ ->\ Num) +.BI Float.log10\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the base-10 logarithm of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the base-10 logarithm is to be calculated. +x Float The number for which the base-10 logarithm is to be calculated. .TE .SH RETURN The base-10 logarithm of `x`. @@ -32,4 +32,4 @@ The base-10 logarithm of `x`. assert (100.0).log10() == 2 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.log1p.3 b/man/man3/tomo-Float.log1p.3 index 677b101d..bfb86cbc 100644 --- a/man/man3/tomo-Num.log1p.3 +++ b/man/man3/tomo-Float.log1p.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.log1p 3 2025-11-29 "Tomo man-pages" +.TH Float.log1p 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.log1p \- logarithm of 1 plus x +Float.log1p \- logarithm of 1 plus x .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.log1p\ :\ func(x:\ Num\ ->\ Num) +.BI Float.log1p\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes $\log(1 + x)$ for a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which $\log(1 + x)$ is to be calculated. +x Float The number for which $\log(1 + x)$ is to be calculated. .TE .SH RETURN The value of $\log(1 + x)$. @@ -32,4 +32,4 @@ The value of $\log(1 + x)$. assert (1.0).log1p() == 0.6931 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.log2.3 b/man/man3/tomo-Float.log2.3 index 4599df08..9cea62d9 100644 --- a/man/man3/tomo-Num.log2.3 +++ b/man/man3/tomo-Float.log2.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.log2 3 2025-11-29 "Tomo man-pages" +.TH Float.log2 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.log2 \- logarithm base-2 +Float.log2 \- logarithm base-2 .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.log2\ :\ func(x:\ Num\ ->\ Num) +.BI Float.log2\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the base-2 logarithm of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the base-2 logarithm is to be calculated. +x Float The number for which the base-2 logarithm is to be calculated. .TE .SH RETURN The base-2 logarithm of `x`. @@ -32,4 +32,4 @@ The base-2 logarithm of `x`. assert (8.0).log2() == 3 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.logb.3 b/man/man3/tomo-Float.logb.3 index a6930551..38ac47f6 100644 --- a/man/man3/tomo-Num.logb.3 +++ b/man/man3/tomo-Float.logb.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.logb 3 2025-11-29 "Tomo man-pages" +.TH Float.logb 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.logb \- exponent of a floating point value +Float.logb \- exponent of a floating point value .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.logb\ :\ func(x:\ Num\ ->\ Num) +.BI Float.logb\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the binary exponent (base-2 logarithm) of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the binary exponent is to be calculated. +x Float The number for which the binary exponent is to be calculated. .TE .SH RETURN The binary exponent of `x`. @@ -32,4 +32,4 @@ The binary exponent of `x`. assert (8.0).logb() == 3 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.mix.3 b/man/man3/tomo-Float.mix.3 index 0514de66..0bbd1f04 100644 --- a/man/man3/tomo-Num.mix.3 +++ b/man/man3/tomo-Float.mix.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.mix 3 2025-11-29 "Tomo man-pages" +.TH Float.mix 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.mix \- mix two numbers by an amount +Float.mix \- mix two numbers by an amount .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.mix\ :\ func(amount:\ Num,\ x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.mix\ :\ func(amount:\ Float,\ x:\ Float,\ y:\ Float\ ->\ Float) .fi .SH DESCRIPTION Interpolates between two numbers based on a given amount. @@ -22,9 +22,9 @@ allbox; lb lb lbx l l l. Name Type Description -amount Num The interpolation factor (between \fB0\fR and \fB1\fR). -x Num The starting number. -y Num The ending number. +amount Float The interpolation factor (between \fB0\fR and \fB1\fR). +x Float The starting number. +y Float The ending number. .TE .SH RETURN The interpolated number between `x` and `y` based on `amount`. @@ -35,4 +35,4 @@ assert (0.5).mix(10, 20) == 15 assert (0.25).mix(10, 20) == 12.5 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.near.3 b/man/man3/tomo-Float.near.3 index 824ba241..6418dc1f 100644 --- a/man/man3/tomo-Num.near.3 +++ b/man/man3/tomo-Float.near.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.near 3 2025-11-29 "Tomo man-pages" +.TH Float.near 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.near \- check if two numbers are near each other +Float.near \- check if two numbers are near each other .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.near\ :\ func(x:\ Num,\ y:\ Num,\ ratio:\ Num\ =\ 1e-9,\ min_epsilon:\ Num\ =\ 1e-9\ ->\ Bool) +.BI Float.near\ :\ func(x:\ Float,\ y:\ Float,\ ratio:\ Float\ =\ 1e-9,\ min_epsilon:\ Float\ =\ 1e-9\ ->\ Bool) .fi .SH DESCRIPTION Checks if two numbers are approximately equal within specified tolerances. If two numbers are within an absolute difference or the ratio between the two is small enough, they are considered near each other. @@ -22,10 +22,10 @@ allbox; lb lb lbx lb l l l l. Name Type Description Default -x Num The first number. - -y Num The second number. - -ratio Num The relative tolerance. Default is \fB1e-9\fR. 1e-9 -min_epsilon Num The absolute tolerance. Default is \fB1e-9\fR. 1e-9 +x Float The first number. - +y Float The second number. - +ratio Float The relative tolerance. Default is \fB1e-9\fR. 1e-9 +min_epsilon Float The absolute tolerance. Default is \fB1e-9\fR. 1e-9 .TE .SH RETURN `yes` if `x` and `y` are approximately equal within the specified tolerances, `no` otherwise. @@ -37,4 +37,4 @@ assert (100.0).near(110, ratio=0.1) == yes assert (5.0).near(5.1, min_epsilon=0.1) == yes .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.nextafter.3 b/man/man3/tomo-Float.nextafter.3 index 1379239b..69c07eca 100644 --- a/man/man3/tomo-Num.nextafter.3 +++ b/man/man3/tomo-Float.nextafter.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.nextafter 3 2025-11-29 "Tomo man-pages" +.TH Float.nextafter 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.nextafter \- next floating point number +Float.nextafter \- next floating point number .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.nextafter\ :\ func(x:\ Num,\ y:\ Num\ ->\ Num) +.BI Float.nextafter\ :\ func(x:\ Float,\ y:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the next representable value after a given number towards a specified direction. @@ -22,8 +22,8 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The starting number. -y Num The direction towards which to find the next representable value. +x Float The starting number. +y Float The direction towards which to find the next representable value. .TE .SH RETURN The next representable value after `x` in the direction of `y`. @@ -33,4 +33,4 @@ The next representable value after `x` in the direction of `y`. assert (1.0).nextafter(1.1) == 1.0000000000000002 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.parse.3 b/man/man3/tomo-Float.parse.3 index 0df34a8f..d8c27f11 100644 --- a/man/man3/tomo-Num.parse.3 +++ b/man/man3/tomo-Float.parse.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.parse 3 2025-11-29 "Tomo man-pages" +.TH Float.parse 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.parse \- convert text to number +Float.parse \- convert text to number .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.parse\ :\ func(text:\ Text,\ remainder:\ &Text?\ =\ none\ ->\ Num?) +.BI Float.parse\ :\ func(text:\ Text,\ remainder:\ &Text?\ =\ none\ ->\ Float?) .fi .SH DESCRIPTION Converts a text representation of a number into a floating-point number. @@ -30,12 +30,12 @@ The number represented by the text or `none` if the entire text can't be parsed .SH EXAMPLES .EX -assert Num.parse("3.14") == 3.14 -assert Num.parse("1e3") == 1000 -assert Num.parse("1.5junk") == none +assert Float.parse("3.14") == 3.14 +assert Float.parse("1e3") == 1000 +assert Float.parse("1.5junk") == none remainder : Text -assert Num.parse("1.5junk", &remainder) == 1.5 +assert Float.parse("1.5junk", &remainder) == 1.5 assert remainder == "junk" .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.percent.3 b/man/man3/tomo-Float.percent.3 index 4102bc86..b079b7fb 100644 --- a/man/man3/tomo-Num.percent.3 +++ b/man/man3/tomo-Float.percent.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.percent 3 2025-11-29 "Tomo man-pages" +.TH Float.percent 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.percent \- format as a percentage +Float.percent \- format as a percentage .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.percent\ :\ func(n:\ Num,\ precision:\ Num\ =\ 0.01\ ->\ Text) +.BI Float.percent\ :\ func(n:\ Float,\ precision:\ Float\ =\ 0.01\ ->\ Text) .fi .SH DESCRIPTION Convert a number into a percentage text with a percent sign. @@ -22,8 +22,8 @@ allbox; lb lb lbx lb l l l l. Name Type Description Default -n Num The number to be converted to a percent. - -precision Num Round the percentage to this precision level. 0.01 +n Float The number to be converted to a percent. - +precision Float Round the percentage to this precision level. 0.01 .TE .SH RETURN A text representation of the number as a percentage with a percent sign. @@ -36,4 +36,4 @@ assert (1./3.).percent(2, precision=0.0001) == "33.3333%" assert (1./3.).percent(2, precision=10.) == "30%" .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.rint.3 b/man/man3/tomo-Float.rint.3 index 948838be..026c4284 100644 --- a/man/man3/tomo-Num.rint.3 +++ b/man/man3/tomo-Float.rint.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.rint 3 2025-11-29 "Tomo man-pages" +.TH Float.rint 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.rint \- round to nearest integer +Float.rint \- round to nearest integer .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.rint\ :\ func(x:\ Num\ ->\ Num) +.BI Float.rint\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Rounds a number to the nearest integer, with ties rounded to the nearest even integer. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number to be rounded. +x Float The number to be rounded. .TE .SH RETURN The nearest integer value of `x`. @@ -33,4 +33,4 @@ assert (3.5).rint() == 4 assert (2.5).rint() == 2 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.round.3 b/man/man3/tomo-Float.round.3 index 712d3038..584f53b1 100644 --- a/man/man3/tomo-Num.round.3 +++ b/man/man3/tomo-Float.round.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.round 3 2025-11-29 "Tomo man-pages" +.TH Float.round 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.round \- round to nearest integer +Float.round \- round to nearest integer .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.round\ :\ func(x:\ Num\ ->\ Num) +.BI Float.round\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Rounds a number to the nearest whole number integer. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number to be rounded. +x Float The number to be rounded. .TE .SH RETURN The nearest integer value of `x`. @@ -33,4 +33,4 @@ assert (2.3).round() == 2 assert (2.7).round() == 3 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.significand.3 b/man/man3/tomo-Float.significand.3 index 4f78407d..e184ea92 100644 --- a/man/man3/tomo-Num.significand.3 +++ b/man/man3/tomo-Float.significand.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.significand 3 2025-11-29 "Tomo man-pages" +.TH Float.significand 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.significand \- get mantissa +Float.significand \- get mantissa .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.significand\ :\ func(x:\ Num\ ->\ Num) +.BI Float.significand\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Extracts the significand (or mantissa) of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number from which to extract the significand. +x Float The number from which to extract the significand. .TE .SH RETURN The significand of `x`. @@ -32,4 +32,4 @@ The significand of `x`. assert (1234.567).significand() == 0.1234567 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.sin.3 b/man/man3/tomo-Float.sin.3 index 826035bf..c5b16683 100644 --- a/man/man3/tomo-Num.sin.3 +++ b/man/man3/tomo-Float.sin.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.sin 3 2025-11-29 "Tomo man-pages" +.TH Float.sin 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.sin \- sine +Float.sin \- sine .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.sin\ :\ func(x:\ Num\ ->\ Num) +.BI Float.sin\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the sine of a number (angle in radians). @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The angle in radians. +x Float The angle in radians. .TE .SH RETURN The sine of `x`. @@ -32,4 +32,4 @@ The sine of `x`. assert (0.0).sin() == 0 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.sinh.3 b/man/man3/tomo-Float.sinh.3 index a65c19a9..53f95562 100644 --- a/man/man3/tomo-Num.sinh.3 +++ b/man/man3/tomo-Float.sinh.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.sinh 3 2025-11-29 "Tomo man-pages" +.TH Float.sinh 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.sinh \- hyperbolic sine +Float.sinh \- hyperbolic sine .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.sinh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.sinh\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the hyperbolic sine of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the hyperbolic sine is to be calculated. +x Float The number for which the hyperbolic sine is to be calculated. .TE .SH RETURN The hyperbolic sine of `x`. @@ -32,4 +32,4 @@ The hyperbolic sine of `x`. assert (0.0).sinh() == 0 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.sqrt.3 b/man/man3/tomo-Float.sqrt.3 index 5ade1af5..47e81d53 100644 --- a/man/man3/tomo-Num.sqrt.3 +++ b/man/man3/tomo-Float.sqrt.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.sqrt 3 2025-11-29 "Tomo man-pages" +.TH Float.sqrt 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.sqrt \- square root +Float.sqrt \- square root .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.sqrt\ :\ func(x:\ Num\ ->\ Num) +.BI Float.sqrt\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the square root of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the square root is to be calculated. +x Float The number for which the square root is to be calculated. .TE .SH RETURN The square root of `x`. @@ -32,4 +32,4 @@ The square root of `x`. assert (16.0).sqrt() == 4 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.tan.3 b/man/man3/tomo-Float.tan.3 index 7370d4b6..bd404863 100644 --- a/man/man3/tomo-Num.tan.3 +++ b/man/man3/tomo-Float.tan.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.tan 3 2025-11-29 "Tomo man-pages" +.TH Float.tan 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.tan \- tangent +Float.tan \- tangent .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.tan\ :\ func(x:\ Num\ ->\ Num) +.BI Float.tan\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the tangent of a number (angle in radians). @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The angle in radians. +x Float The angle in radians. .TE .SH RETURN The tangent of `x`. @@ -32,4 +32,4 @@ The tangent of `x`. assert (0.0).tan() == 0 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.tanh.3 b/man/man3/tomo-Float.tanh.3 index 51dca0c6..9826595b 100644 --- a/man/man3/tomo-Num.tanh.3 +++ b/man/man3/tomo-Float.tanh.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.tanh 3 2025-11-29 "Tomo man-pages" +.TH Float.tanh 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.tanh \- hyperbolic tangent +Float.tanh \- hyperbolic tangent .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.tanh\ :\ func(x:\ Num\ ->\ Num) +.BI Float.tanh\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the hyperbolic tangent of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the hyperbolic tangent is to be calculated. +x Float The number for which the hyperbolic tangent is to be calculated. .TE .SH RETURN The hyperbolic tangent of `x`. @@ -32,4 +32,4 @@ The hyperbolic tangent of `x`. assert (0.0).tanh() == 0 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.tgamma.3 b/man/man3/tomo-Float.tgamma.3 index 13d7ff5d..f355b436 100644 --- a/man/man3/tomo-Num.tgamma.3 +++ b/man/man3/tomo-Float.tgamma.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.tgamma 3 2025-11-29 "Tomo man-pages" +.TH Float.tgamma 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.tgamma \- true gamma function +Float.tgamma \- true gamma function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.tgamma\ :\ func(x:\ Num\ ->\ Num) +.BI Float.tgamma\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the gamma function of a number. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the gamma function is to be calculated. +x Float The number for which the gamma function is to be calculated. .TE .SH RETURN The gamma function of `x`. @@ -32,4 +32,4 @@ The gamma function of `x`. assert (1.0).tgamma() == 1 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.trunc.3 b/man/man3/tomo-Float.trunc.3 index 4ba83aa2..3b041c9f 100644 --- a/man/man3/tomo-Num.trunc.3 +++ b/man/man3/tomo-Float.trunc.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.trunc 3 2025-11-29 "Tomo man-pages" +.TH Float.trunc 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.trunc \- truncate a number +Float.trunc \- truncate a number .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.trunc\ :\ func(x:\ Num\ ->\ Num) +.BI Float.trunc\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Truncates a number to the nearest integer towards zero. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number to be truncated. +x Float The number to be truncated. .TE .SH RETURN The integer part of `x` towards zero. @@ -33,4 +33,4 @@ assert (3.7).trunc() == 3 assert (-3.7).trunc() == -3 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.with_precision.3 b/man/man3/tomo-Float.with_precision.3 index aee46a28..7746bde7 100644 --- a/man/man3/tomo-Num.with_precision.3 +++ b/man/man3/tomo-Float.with_precision.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.with_precision 3 2025-11-29 "Tomo man-pages" +.TH Float.with_precision 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.with_precision \- round to a given precision +Float.with_precision \- round to a given precision .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.with_precision\ :\ func(n:\ Num,\ precision:\ Num\ ->\ Num) +.BI Float.with_precision\ :\ func(n:\ Float,\ precision:\ Float\ ->\ Float) .fi .SH DESCRIPTION Round a number to the given precision level (specified as `10`, `.1`, `.001` etc). @@ -22,8 +22,8 @@ allbox; lb lb lbx l l l. Name Type Description -n Num The number to be rounded to a given precision. -precision Num The precision to which the number should be rounded. +n Float The number to be rounded to a given precision. +precision Float The precision to which the number should be rounded. .TE .SH RETURN The number, rounded to the given precision level. @@ -35,4 +35,4 @@ assert (123456.).with_precision(100) == 123500 assert (1234567.).with_precision(5) == 1234565 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.y0.3 b/man/man3/tomo-Float.y0.3 index 6b692de2..c3089d36 100644 --- a/man/man3/tomo-Num.y0.3 +++ b/man/man3/tomo-Float.y0.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.y0 3 2025-11-29 "Tomo man-pages" +.TH Float.y0 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.y0 \- Bessel function +Float.y0 \- Bessel function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.y0\ :\ func(x:\ Num\ ->\ Num) +.BI Float.y0\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the Bessel function of the second kind of order 0. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the Bessel function is to be calculated. +x Float The number for which the Bessel function is to be calculated. .TE .SH RETURN The Bessel function of the second kind of order 0 of `x`. @@ -32,4 +32,4 @@ The Bessel function of the second kind of order 0 of `x`. assert (1.0).y0() == -0.7652 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-Num.y1.3 b/man/man3/tomo-Float.y1.3 index d1e98bad..cbf1ab45 100644 --- a/man/man3/tomo-Num.y1.3 +++ b/man/man3/tomo-Float.y1.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH Num.y1 3 2025-11-29 "Tomo man-pages" +.TH Float.y1 3 2025-12-11 "Tomo man-pages" .SH NAME -Num.y1 \- Bessel function +Float.y1 \- Bessel function .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI Num.y1\ :\ func(x:\ Num\ ->\ Num) +.BI Float.y1\ :\ func(x:\ Float\ ->\ Float) .fi .SH DESCRIPTION Computes the Bessel function of the second kind of order 1. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -x Num The number for which the Bessel function is to be calculated. +x Float The number for which the Bessel function is to be calculated. .TE .SH RETURN The Bessel function of the second kind of order 1 of `x`. @@ -32,4 +32,4 @@ The Bessel function of the second kind of order 1 of `x`. assert (1.0).y1() == 0.4401 .EE .SH SEE ALSO -.BR Tomo-Num (3) +.BR Tomo-Float (3) diff --git a/man/man3/tomo-List.3 b/man/man3/tomo-List.3 index 5ff85015..3da6389f 100644 --- a/man/man3/tomo-List.3 +++ b/man/man3/tomo-List.3 @@ -2,7 +2,7 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH List 3 2025-11-29 "Tomo man-pages" +.TH List 3 2025-12-11 "Tomo man-pages" .SH NAME List \- a Tomo type .SH LIBRARY @@ -147,7 +147,7 @@ For more, see: .TP -.BI List.sample\ :\ func(list:\ [T],\ count:\ Int,\ weights:\ [Num]?\ =\ none,\ random:\ func(->Num)?\ =\ none\ ->\ [T]) +.BI List.sample\ :\ func(list:\ [T],\ count:\ Int,\ weights:\ [Float64]?\ =\ none,\ random:\ func(->Float64)?\ =\ none\ ->\ [T]) Selects a sample of elements from the list, optionally with weighted probabilities. For more, see: diff --git a/man/man3/tomo-List.sample.3 b/man/man3/tomo-List.sample.3 index 29ad8563..126e6ede 100644 --- a/man/man3/tomo-List.sample.3 +++ b/man/man3/tomo-List.sample.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH List.sample 3 2025-11-29 "Tomo man-pages" +.TH List.sample 3 2025-12-11 "Tomo man-pages" .SH NAME List.sample \- weighted random choices .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI List.sample\ :\ func(list:\ [T],\ count:\ Int,\ weights:\ [Num]?\ =\ none,\ random:\ func(->Num)?\ =\ none\ ->\ [T]) +.BI List.sample\ :\ func(list:\ [T],\ count:\ Int,\ weights:\ [Float64]?\ =\ none,\ random:\ func(->Float64)?\ =\ none\ ->\ [T]) .fi .SH DESCRIPTION Selects a sample of elements from the list, optionally with weighted probabilities. @@ -24,8 +24,8 @@ l l l l. Name Type Description Default list [T] The list to sample from. - count Int The number of elements to sample. - -weights [Num]? The probability weights for each element in the list. These values do not need to add up to any particular number, they are relative weights. If no weights are given, elements will be sampled with uniform probability. none -random func(->Num)? If provided, this function will be used to get random values for sampling the list. The provided function should return random numbers between \fB0.0\fR (inclusive) and \fB1.0\fR (exclusive). (Used for deterministic pseudorandom number generation) none +weights [Float64]? The probability weights for each element in the list. These values do not need to add up to any particular number, they are relative weights. If no weights are given, elements will be sampled with uniform probability. none +random func(->Float64)? If provided, this function will be used to get random values for sampling the list. The provided function should return random numbers between \fB0.0\fR (inclusive) and \fB1.0\fR (exclusive). (Used for deterministic pseudorandom number generation) none .TE .SH RETURN A list of sampled elements from the list. diff --git a/man/man3/tomo-USE_COLOR.3 b/man/man3/tomo-USE_COLOR.3 index 3b48329d..168c3c06 100644 --- a/man/man3/tomo-USE_COLOR.3 +++ b/man/man3/tomo-USE_COLOR.3 @@ -2,7 +2,7 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH USE_COLOR 3 2025-05-17 "Tomo man-pages" +.TH USE_COLOR 3 2025-11-09 "Tomo man-pages" .SH NAME USE_COLOR \- whether to use colors .SH LIBRARY diff --git a/man/man3/tomo-sleep.3 b/man/man3/tomo-sleep.3 index baea8966..a2e4a707 100644 --- a/man/man3/tomo-sleep.3 +++ b/man/man3/tomo-sleep.3 @@ -2,14 +2,14 @@ .\" Copyright (c) 2025 Bruce Hill .\" All rights reserved. .\" -.TH sleep 3 2025-11-29 "Tomo man-pages" +.TH sleep 3 2025-12-11 "Tomo man-pages" .SH NAME sleep \- wait for an interval .SH LIBRARY Tomo Standard Library .SH SYNOPSIS .nf -.BI sleep\ :\ func(seconds:\ Num\ ->\ Void) +.BI sleep\ :\ func(seconds:\ Float64\ ->\ Void) .fi .SH DESCRIPTION Pause execution for a given number of seconds. @@ -22,7 +22,7 @@ allbox; lb lb lbx l l l. Name Type Description -seconds Num How many seconds to sleep for. +seconds Float64 How many seconds to sleep for. .TE .SH RETURN Nothing. diff --git a/src/compile/assignments.c b/src/compile/assignments.c index 74a00e0b..8c6af3ee 100644 --- a/src/compile/assignments.c +++ b/src/compile/assignments.c @@ -22,22 +22,22 @@ Text_t compile_update_assignment(env_t *env, ast_t *ast) { Text_t update_assignment = EMPTY_TEXT; switch (ast->tag) { case PlusUpdate: { - if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType) + if (lhs_t->tag == IntType || lhs_t->tag == FloatType || lhs_t->tag == ByteType) update_assignment = Texts(lhs, " += ", compile_to_type(env, update.rhs, lhs_t), ";"); break; } case MinusUpdate: { - if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType) + if (lhs_t->tag == IntType || lhs_t->tag == FloatType || lhs_t->tag == ByteType) update_assignment = Texts(lhs, " -= ", compile_to_type(env, update.rhs, lhs_t), ";"); break; } case MultiplyUpdate: { - if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType) + if (lhs_t->tag == IntType || lhs_t->tag == FloatType || lhs_t->tag == ByteType) update_assignment = Texts(lhs, " *= ", compile_to_type(env, update.rhs, lhs_t), ";"); break; } case DivideUpdate: { - if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType) + if (lhs_t->tag == IntType || lhs_t->tag == FloatType || lhs_t->tag == ByteType) update_assignment = Texts(lhs, " /= ", compile_to_type(env, update.rhs, lhs_t), ";"); break; } diff --git a/src/compile/binops.c b/src/compile/binops.c index acf1e031..a84e34ba 100644 --- a/src/compile/binops.c +++ b/src/compile/binops.c @@ -113,14 +113,15 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { switch (ast->tag) { case Power: { - if (overall_t->tag != NumType) - code_err(ast, "Exponentiation is only supported for Num types, not ", type_to_text(overall_t)); - if (overall_t->tag == NumType && Match(overall_t, NumType)->bits == TYPE_NBITS32) + if (overall_t->tag != FloatType) + code_err(ast, "Exponentiation is only supported for floating point number types, not ", + type_to_text(overall_t)); + if (overall_t->tag == FloatType && Match(overall_t, FloatType)->bits == TYPE_NBITS32) return Texts("powf(", lhs, ", ", rhs, ")"); else return Texts("pow(", lhs, ", ", rhs, ")"); } case Multiply: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", @@ -128,7 +129,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { return Texts("(", lhs, " * ", rhs, ")"); } case Divide: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", @@ -136,7 +137,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { return Texts("(", lhs, " / ", rhs, ")"); } case Mod: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", @@ -144,7 +145,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { return Texts("(", lhs, " % ", rhs, ")"); } case Mod1: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", @@ -152,7 +153,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { return Texts("((((", lhs, ")-1) % (", rhs, ")) + 1)"); } case Plus: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", @@ -160,7 +161,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { return Texts("(", lhs, " + ", rhs, ")"); } case Minus: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", @@ -168,7 +169,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { return Texts("(", lhs, " - ", rhs, ")"); } case LeftShift: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", @@ -176,7 +177,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { return Texts("(", lhs, " << ", rhs, ")"); } case RightShift: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", @@ -184,7 +185,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { return Texts("(", lhs, " >> ", rhs, ")"); } case UnsignedLeftShift: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", @@ -192,7 +193,7 @@ Text_t compile_binary_op(env_t *env, ast_t *ast) { return Texts("(", compile_type(overall_t), ")((", compile_unsigned_type(lhs_t), ")", lhs, " << ", rhs, ")"); } case UnsignedRightShift: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != FloatType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same " "numeric type, not ", diff --git a/src/compile/comparisons.c b/src/compile/comparisons.c index c2d376ef..afb5dc15 100644 --- a/src/compile/comparisons.c +++ b/src/compile/comparisons.c @@ -53,7 +53,7 @@ Text_t compile_comparison(env_t *env, ast_t *ast) { case BoolType: case ByteType: case IntType: - case NumType: + case FloatType: case PointerType: case FunctionType: return Texts("(", lhs, ast->tag == Equals ? " == " : " != ", rhs, ")"); default: @@ -97,7 +97,7 @@ Text_t compile_comparison(env_t *env, ast_t *ast) { case BoolType: case ByteType: case IntType: - case NumType: + case FloatType: case PointerType: case FunctionType: return Texts("(", lhs, " ", op, " ", rhs, ")"); default: diff --git a/src/compile/expressions.c b/src/compile/expressions.c index c3918de3..638480bd 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -82,8 +82,8 @@ Text_t compile_empty(type_t *t) { return empty_pointed.length == 0 ? EMPTY_TEXT : Texts(ptr->is_stack ? Text("stack(") : Text("heap("), empty_pointed, ")"); } - case NumType: { - return Match(t, NumType)->bits == TYPE_NBITS32 ? Text("N32(0.0f)") : Text("N64(0.0)"); + case FloatType: { + return Match(t, FloatType)->bits == TYPE_NBITS32 ? Text("F32(0.0f)") : Text("F64(0.0)"); } case StructType: return compile_empty_struct(t); case EnumType: return compile_empty_enum(t); @@ -108,7 +108,13 @@ Text_t compile(env_t *env, ast_t *ast) { } case Int: return compile_int(ast); case Num: { - return Text$from_str(String(hex_double(Match(ast, Num)->n))); + // return Text$from_str(String(hex_double(Match(ast, Num)->n))); + Text_t original = Text$from_str(String(string_slice(ast->start, (size_t)(ast->end - ast->start)))); + original = Text$replace(original, Text("_"), EMPTY_TEXT); + original = Text$replace(original, Text("("), EMPTY_TEXT); + original = Text$replace(original, Text(")"), EMPTY_TEXT); + original = Text$replace(original, Text(" "), EMPTY_TEXT); + return Texts("Real$parse(Text(\"", original, "\"), NULL)"); } case Not: { ast_t *value = Match(ast, Not)->value; @@ -140,7 +146,7 @@ Text_t compile(env_t *env, ast_t *ast) { return Texts(b->code, "(", compile_arguments(env, ast, fn->args, new (arg_ast_t, .value = value)), ")"); } - if (t->tag == IntType || t->tag == NumType) return Texts("-(", compile(env, value), ")"); + if (t->tag == IntType || t->tag == FloatType) return Texts("-(", compile(env, value), ")"); code_err(ast, "I don't know how to get the negative value of type ", type_to_text(t)); } @@ -196,7 +202,7 @@ Text_t compile(env_t *env, ast_t *ast) { if (key_t->tag == BigIntType) comparison = Texts("(Int$compare_value(", lhs_key, ", ", rhs_key, ")", (ast->tag == Min ? "<=" : ">="), "0)"); - else if (key_t->tag == IntType || key_t->tag == NumType || key_t->tag == BoolType || key_t->tag == PointerType + else if (key_t->tag == IntType || key_t->tag == FloatType || key_t->tag == BoolType || key_t->tag == PointerType || key_t->tag == ByteType) comparison = Texts("((", lhs_key, ")", (ast->tag == Min ? "<=" : ">="), "(", rhs_key, "))"); else diff --git a/src/compile/functions.c b/src/compile/functions.c index f62e00f8..cadd0453 100644 --- a/src/compile/functions.c +++ b/src/compile/functions.c @@ -5,8 +5,8 @@ #include "../naming.h" #include "../stdlib/c_strings.h" #include "../stdlib/datatypes.h" +#include "../stdlib/floats.h" #include "../stdlib/integers.h" -#include "../stdlib/nums.h" #include "../stdlib/optionals.h" #include "../stdlib/tables.h" #include "../stdlib/text.h" @@ -81,12 +81,12 @@ Text_t compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_ Text_t value; if (spec_arg->type->tag == IntType && call_arg->value->tag == Int) { value = compile_int_to_type(env, call_arg->value, spec_arg->type); - } else if (spec_arg->type->tag == NumType && call_arg->value->tag == Int) { + } else if (spec_arg->type->tag == FloatType && call_arg->value->tag == Int) { OptionalInt_t int_val = Int$from_str(Match(call_arg->value, Int)->str); if (int_val.small == 0) code_err(call_arg->value, "Failed to parse this integer"); - if (Match(spec_arg->type, NumType)->bits == TYPE_NBITS64) - value = Text$from_str(String(hex_double(Num$from_int(int_val, false)))); - else value = Text$from_str(String(hex_double((double)Num32$from_int(int_val, false)), "f")); + if (Match(spec_arg->type, FloatType)->bits == TYPE_NBITS64) + value = Text$from_str(String(hex_double(Float64$from_int(int_val, false)))); + else value = Text$from_str(String(hex_double((double)Float32$from_int(int_val, false)), "f")); } else { env_t *arg_env = with_enum_scope(env, spec_arg->type); value = compile_maybe_incref(arg_env, call_arg->value, spec_arg->type); @@ -105,12 +105,12 @@ Text_t compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_ Text_t value; if (spec_arg->type->tag == IntType && call_arg->value->tag == Int) { value = compile_int_to_type(env, call_arg->value, spec_arg->type); - } else if (spec_arg->type->tag == NumType && call_arg->value->tag == Int) { + } else if (spec_arg->type->tag == FloatType && call_arg->value->tag == Int) { OptionalInt_t int_val = Int$from_str(Match(call_arg->value, Int)->str); if (int_val.small == 0) code_err(call_arg->value, "Failed to parse this integer"); - if (Match(spec_arg->type, NumType)->bits == TYPE_NBITS64) - value = Text$from_str(String(hex_double(Num$from_int(int_val, false)))); - else value = Text$from_str(String(hex_double((double)Num32$from_int(int_val, false)), "f")); + if (Match(spec_arg->type, FloatType)->bits == TYPE_NBITS64) + value = Text$from_str(String(hex_double(Float64$from_int(int_val, false)))); + else value = Text$from_str(String(hex_double((double)Float32$from_int(int_val, false)), "f")); } else { env_t *arg_env = with_enum_scope(env, spec_arg->type); value = compile_maybe_incref(arg_env, call_arg->value, spec_arg->type); @@ -181,7 +181,7 @@ Text_t compile_function_call(env_t *env, ast_t *ast) { // not go through any conversion, just a cast: if (is_numeric_type(t) && call->args && !call->args->next && call->args->value->tag == Int) return compile_to_type(env, call->args->value, t); - else if (t->tag == NumType && call->args && !call->args->next && call->args->value->tag == Num) + else if (t->tag == FloatType && call->args && !call->args->next && call->args->value->tag == Num) return compile_to_type(env, call->args->value, t); binding_t *constructor = diff --git a/src/compile/integers.c b/src/compile/integers.c index 78d48b70..219847cf 100644 --- a/src/compile/integers.c +++ b/src/compile/integers.c @@ -49,11 +49,11 @@ Text_t compile_int_to_type(env_t *env, ast_t *ast, type_t *target) { if (target->tag == ByteType) { if (mpz_cmp_si(i, UINT8_MAX) <= 0 && mpz_cmp_si(i, 0) >= 0) return Texts("(Byte_t)(", c_literal, ")"); code_err(ast, "This integer cannot fit in a byte"); - } else if (target->tag == NumType) { - if (Match(target, NumType)->bits == TYPE_NBITS64) { - return Texts("N64(", c_literal, ")"); + } else if (target->tag == FloatType) { + if (Match(target, FloatType)->bits == TYPE_NBITS64) { + return Texts("F64(", c_literal, ")"); } else { - return Texts("N32(", c_literal, ")"); + return Texts("F32(", c_literal, ")"); } } else if (target->tag == IntType) { int64_t target_bits = (int64_t)Match(target, IntType)->bits; diff --git a/src/compile/lists.c b/src/compile/lists.c index 31255c1e..f39f61d8 100644 --- a/src/compile/lists.c +++ b/src/compile/lists.c @@ -113,12 +113,12 @@ Text_t compile_list_method_call(env_t *env, ast_t *ast) { return Texts("List$has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "sample")) { - type_t *random_num_type = parse_type_string(env, "func(->Num)?"); + type_t *random_num_type = parse_type_string(env, "func(->Float64)?"); self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new (arg_t, .name = "count", .type = INT_TYPE, .next = new ( - arg_t, .name = "weights", .type = Type(ListType, .item_type = Type(NumType, .bits = TYPE_NBITS64)), + arg_t, .name = "weights", .type = Type(ListType, .item_type = Type(FloatType, .bits = TYPE_NBITS64)), .default_val = FakeAST(None), .next = new (arg_t, .name = "random", .type = random_num_type, .default_val = FakeAST(None)))); return Texts("List$sample(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", diff --git a/src/compile/optionals.c b/src/compile/optionals.c index 75dff935..f54d8931 100644 --- a/src/compile/optionals.c +++ b/src/compile/optionals.c @@ -70,7 +70,7 @@ Text_t compile_none(type_t *t) { case CStringType: return Text("NULL"); case PointerType: return Texts("((", compile_type(t), ")NULL)"); case ClosureType: return Text("NONE_CLOSURE"); - case NumType: return Text("nan(\"none\")"); + case FloatType: return Text("nan(\"none\")"); case StructType: return Texts("((", compile_type(Type(OptionalType, .type = t)), "){.has_value=false})"); case EnumType: { env_t *enum_env = Match(t, EnumType)->env; @@ -89,8 +89,8 @@ Text_t check_none(type_t *t, Text_t value) { if (t->tag == PointerType || t->tag == FunctionType || t->tag == CStringType) return Texts("(", value, " == NULL)"); else if (t->tag == BigIntType) return Texts("((", value, ").small == 0)"); else if (t->tag == ClosureType) return Texts("((", value, ").fn == NULL)"); - else if (t->tag == NumType) - return Texts(Match(t, NumType)->bits == TYPE_NBITS64 ? "Num$isnan(" : "Num32$isnan(", value, ")"); + else if (t->tag == FloatType) + return Texts(Match(t, FloatType)->bits == TYPE_NBITS64 ? "Float64$isnan(" : "Float32$isnan(", value, ")"); else if (t->tag == ListType) return Texts("((", value, ").data == NULL)"); else if (t->tag == TableType) return Texts("((", value, ").entries.data == NULL)"); else if (t->tag == BoolType) return Texts("((", value, ") == NONE_BOOL)"); diff --git a/src/compile/promotions.c b/src/compile/promotions.c index 7a169821..151850f0 100644 --- a/src/compile/promotions.c +++ b/src/compile/promotions.c @@ -61,7 +61,8 @@ bool promote(env_t *env, ast_t *ast, Text_t *code, type_t *actual, type_t *neede if (actual->tag == TextType && needed->tag == TextType && streq(Match(needed, TextType)->lang, "Text")) return true; // Automatic optional checking for nums: - if (needed->tag == NumType && actual->tag == OptionalType && Match(actual, OptionalType)->type->tag == NumType) { + if (needed->tag == FloatType && actual->tag == OptionalType + && Match(actual, OptionalType)->type->tag == FloatType) { int64_t line = get_line_number(ast->file, ast->start); *code = Texts("({ ", compile_declaration(actual, Text("opt")), " = ", *code, "; ", "if unlikely (", check_none(actual, Text("opt")), ")\n", "#line ", line, "\n", "fail_source(", @@ -138,9 +139,9 @@ Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t) { if (ast->tag == Int && is_numeric_type(non_optional(t))) { return compile_int_to_type(env, ast, t); - } else if (ast->tag == Num && t->tag == NumType) { + } else if (ast->tag == Num && t->tag == FloatType) { double n = Match(ast, Num)->n; - switch (Match(t, NumType)->bits) { + switch (Match(t, FloatType)->bits) { case TYPE_NBITS64: return Text$from_str(String(hex_double(n))); case TYPE_NBITS32: return Text$from_str(String(hex_double(n), "f")); default: code_err(ast, "This is not a valid number bit width"); diff --git a/src/compile/statements.c b/src/compile/statements.c index 13dcc064..c9a0fd0e 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -28,7 +28,7 @@ Text_t with_source_info(env_t *env, ast_t *ast, Text_t code) { static Text_t compile_simple_update_assignment(env_t *env, ast_t *ast, const char *op) { binary_operands_t update = BINARY_OPERANDS(ast); type_t *lhs_t = get_type(env, update.lhs); - if (is_idempotent(update.lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) + if (is_idempotent(update.lhs) && (lhs_t->tag == IntType || lhs_t->tag == FloatType || lhs_t->tag == ByteType)) return Texts(compile_lvalue(env, update.lhs), " ", op, "= ", compile_to_type(env, update.rhs, lhs_t), ";"); return compile_update_assignment(env, ast); } diff --git a/src/compile/text.c b/src/compile/text.c index 2a64ca45..7f11169b 100644 --- a/src/compile/text.c +++ b/src/compile/text.c @@ -23,7 +23,7 @@ Text_t expr_as_text(Text_t expr, type_t *t, Text_t color) { case BigIntType: case IntType: case ByteType: - case NumType: { + case FloatType: { Text_t name = type_to_text(t); return Texts(name, "$as_text(stack(", expr, "), ", color, ", &", name, "$info)"); } diff --git a/src/compile/types.c b/src/compile/types.c index aac27f4c..a581fb61 100644 --- a/src/compile/types.c +++ b/src/compile/types.c @@ -23,9 +23,8 @@ Text_t compile_type(type_t *t) { case CStringType: return Text("const char*"); case BigIntType: return Text("Int_t"); case IntType: return Texts("Int", (int32_t)Match(t, IntType)->bits, "_t"); - case NumType: - return Match(t, NumType)->bits == TYPE_NBITS64 ? Text("Num_t") - : Texts("Num", (int32_t)Match(t, NumType)->bits, "_t"); + case FloatType: return Texts("Float", (int32_t)Match(t, FloatType)->bits, "_t"); + case RealType: return Text("Real_t"); case TextType: { DeclareMatch(text, t, TextType); if (!text->lang || streq(text->lang, "Text")) return Text("Text_t"); @@ -65,7 +64,8 @@ Text_t compile_type(type_t *t) { case TextType: case IntType: case BigIntType: - case NumType: + case FloatType: + case RealType: case BoolType: case ByteType: case ListType: @@ -94,7 +94,8 @@ Text_t compile_type_info(type_t *t) { case ByteType: case IntType: case BigIntType: - case NumType: + case FloatType: + case RealType: case CStringType: return Texts("&", type_to_text(t), "$info"); case TextType: { DeclareMatch(text, t, TextType); diff --git a/src/environment.c b/src/environment.c index 0cbeb0fc..27a57d7a 100644 --- a/src/environment.c +++ b/src/environment.c @@ -229,27 +229,27 @@ env_t *global_env(bool source_mapping) { {"unsigned_right_shifted", "Int8$unsigned_right_shifted", "func(x:Int8,y:Int8 -> Int8)"}, // {"wrapping_minus", "Int8$wrapping_minus", "func(x:Int8,y:Int8 -> Int8)"}, // {"wrapping_plus", "Int8$wrapping_plus", "func(x:Int8,y:Int8 -> Int8)"}, ), -#define C(name) {#name, "M_" #name, "Num"} -#define F(name) {#name, #name, "func(n:Num -> Num)"} -#define F_opt(name) {#name, #name, "func(n:Num -> Num?)"} -#define F2(name) {#name, #name, "func(x,y:Num -> Num)"} +#define C(name) {#name, "M_" #name, "Float64"} +#define F(name) {#name, #name, "func(n:Float64 -> Float64)"} +#define F_opt(name) {#name, #name, "func(n:Float64 -> Float64?)"} +#define F2(name) {#name, #name, "func(x,y:Float64 -> Float64)"} MAKE_TYPE( // - "Num", Type(NumType, .bits = TYPE_NBITS64), Text("Num_t"), Text("Num$info"), - {"near", "Num$near", "func(x,y:Num, ratio=1e-9, min_epsilon=1e-9 -> Bool)"}, // - {"clamped", "Num$clamped", "func(x,low,high:Num -> Num)"}, // - {"percent", "Num$percent", "func(n:Num,precision=0.01 -> Text)"}, // - {"with_precision", "Num$with_precision", "func(n:Num,precision:Num -> Num)"}, // - {"is_between", "Num$is_between", "func(x:Num, a:Num, b:Num -> Bool)"}, // - {"isinf", "Num$isinf", "func(n:Num -> Bool)"}, // - {"isfinite", "Num$isfinite", "func(n:Num -> Bool)"}, // - {"modulo", "Num$mod", "func(x,y:Num -> Num)"}, // - {"modulo1", "Num$mod1", "func(x,y:Num -> Num)"}, // + "Float64", Type(FloatType, .bits = TYPE_NBITS64), Text("Float64_t"), Text("Float64$info"), + {"near", "Float64$near", "func(x,y:Float64, ratio=1e-9, min_epsilon=1e-9 -> Bool)"}, // + {"clamped", "Float64$clamped", "func(x,low,high:Float64 -> Float64)"}, // + {"percent", "Float64$percent", "func(n:Float64,precision=0.01 -> Text)"}, // + {"with_precision", "Float64$with_precision", "func(n:Float64,precision:Float64 -> Float64)"}, // + {"is_between", "Float64$is_between", "func(x:Float64, a:Float64, b:Float64 -> Bool)"}, // + {"isinf", "Float64$isinf", "func(n:Float64 -> Bool)"}, // + {"isfinite", "Float64$isfinite", "func(n:Float64 -> Bool)"}, // + {"modulo", "Float64$mod", "func(x,y:Float64 -> Float64)"}, // + {"modulo1", "Float64$mod1", "func(x,y:Float64 -> Float64)"}, // C(2_SQRTPI), C(E), C(PI_2), C(2_PI), C(1_PI), C(LN10), C(LN2), C(LOG2E), C(PI), C(PI_4), C(SQRT2), - C(SQRT1_2), {"INF", "(Num_t)(INFINITY)", "Num"}, // - {"TAU", "(Num_t)(2.*M_PI)", "Num"}, // - {"mix", "Num$mix", "func(amount,x,y:Num -> Num)"}, // - {"parse", "Num$parse", "func(text:Text, remainder:&Text?=none -> Num?)"}, // - {"abs", "fabs", "func(n:Num -> Num)"}, // + C(SQRT1_2), {"INF", "(Float64_t)(INFINITY)", "Float64"}, // + {"TAU", "(Float64_t)(2.*M_PI)", "Float64"}, // + {"mix", "Float64$mix", "func(amount,x,y:Float64 -> Float64)"}, // + {"parse", "Float64$parse", "func(text:Text, remainder:&Text? = none -> Float64?)"}, // + {"abs", "fabs", "func(n:Float64 -> Float64)"}, // F_opt(acos), F_opt(acosh), F_opt(asin), F(asinh), F(atan), F_opt(atanh), F(cbrt), F(ceil), F_opt(cos), F(cosh), F(erf), F(erfc), F(exp), F(exp2), F(expm1), F(floor), F(j0), F(j1), F_opt(log), F_opt(log10), F_opt(log1p), F_opt(log2), F(logb), F(rint), F(round), F(significand), F_opt(sin), F(sinh), F_opt(sqrt), @@ -259,42 +259,53 @@ env_t *global_env(bool source_mapping) { #undef F_opt #undef F #undef C -#define C(name) {#name, "(Num32_t)(M_" #name ")", "Num32"} -#define F(name) {#name, #name "f", "func(n:Num32 -> Num32)"} -#define F_opt(name) {#name, #name "f", "func(n:Num32 -> Num32?)"} -#define F2(name) {#name, #name "f", "func(x,y:Num32 -> Num32)"} +#define C(name) {#name, "(Float32_t)(M_" #name ")", "Float32"} +#define F(name) {#name, #name "f", "func(n:Float32 -> Float32)"} +#define F_opt(name) {#name, #name "f", "func(n:Float32 -> Float32?)"} +#define F2(name) {#name, #name "f", "func(x,y:Float32 -> Float32)"} MAKE_TYPE( // - "Num32", Type(NumType, .bits = TYPE_NBITS32), Text("Num32_t"), Text("Num32$info"), // - {"near", "Num32$near", "func(x,y:Num32, ratio=Num32(1e-9), min_epsilon=Num32(1e-9) -> Bool)"}, // - {"clamped", "Num32$clamped", "func(x,low,high:Num32 -> Num32)"}, // - {"percent", "Num32$percent", "func(n:Num32,precision=Num32(.01) -> Text)"}, // - {"with_precision", "Num32$with_precision", "func(n:Num32,precision:Num32 -> Num32)"}, // - {"is_between", "Num32$is_between", "func(x:Num32, a:Num32, b:Num32 -> Bool)"}, // - {"isinf", "Num32$isinf", "func(n:Num32 -> Bool)"}, // - {"isfinite", "Num32$isfinite", "func(n:Num32 -> Bool)"}, // + "Float32", Type(FloatType, .bits = TYPE_NBITS32), Text("Float32_t"), Text("Float32$info"), // + {"near", "Float32$near", "func(x,y:Float32, ratio=Float32(1e-9), min_epsilon=Float32(1e-9) -> Bool)"}, // + {"clamped", "Float32$clamped", "func(x,low,high:Float32 -> Float32)"}, // + {"percent", "Float32$percent", "func(n:Float32,precision=Float32(.01) -> Text)"}, // + {"with_precision", "Float32$with_precision", "func(n:Float32,precision:Float32 -> Float32)"}, // + {"is_between", "Float32$is_between", "func(x:Float32, a:Float32, b:Float32 -> Bool)"}, // + {"isinf", "Float32$isinf", "func(n:Float32 -> Bool)"}, // + {"isfinite", "Float32$isfinite", "func(n:Float32 -> Bool)"}, // C(2_SQRTPI), C(E), C(PI_2), C(2_PI), C(1_PI), C(LN10), C(LN2), C(LOG2E), C(PI), C(PI_4), C(SQRT2), C(SQRT1_2), // - {"INF", "(Num32_t)(INFINITY)", "Num32"}, // - {"TAU", "(Num32_t)(2.f*M_PI)", "Num32"}, // - {"mix", "Num32$mix", "func(amount,x,y:Num32 -> Num32)"}, // - {"parse", "Num32$parse", "func(text:Text, remainder:&Text?=none -> Num32?)"}, // - {"abs", "fabsf", "func(n:Num32 -> Num32)"}, // - {"modulo", "Num32$mod", "func(x,y:Num32 -> Num32)"}, // - {"modulo1", "Num32$mod1", "func(x,y:Num32 -> Num32)"}, // + {"INF", "(Float32_t)(INFINITY)", "Float32"}, // + {"TAU", "(Float32_t)(2.f*M_PI)", "Float32"}, // + {"mix", "Float32$mix", "func(amount,x,y:Float32 -> Float32)"}, // + {"parse", "Float32$parse", "func(text:Text, remainder:&Text? = none -> Float32?)"}, // + {"abs", "fabsf", "func(n:Float32 -> Float32)"}, // + {"modulo", "Float32$mod", "func(x,y:Float32 -> Float32)"}, // + {"modulo1", "Float32$mod1", "func(x,y:Float32 -> Float32)"}, // F_opt(acos), F_opt(acosh), F_opt(asin), F(asinh), F(atan), F_opt(atanh), F(cbrt), F(ceil), F_opt(cos), F(cosh), F(erf), F(erfc), F(exp), F(exp2), F(expm1), F(floor), F(j0), F(j1), F_opt(log), F_opt(log10), F_opt(log1p), F_opt(log2), F(logb), F(rint), F(round), F(significand), F_opt(sin), F(sinh), F_opt(sqrt), F_opt(tan), F(tanh), F_opt(tgamma), F(trunc), F_opt(y0), F_opt(y1), F2(atan2), F2(copysign), F2(fdim), F2(hypot), F2(nextafter)), - MAKE_TYPE( // - "CString", Type(CStringType), Text("char*"), Text("CString$info"), // - {"as_text", "Text$from_str", "func(str:CString -> Text)"}, - {"join", "CString$join", "func(glue:CString, pieces:[CString] -> CString)"}), #undef F2 #undef F_opt #undef F #undef C MAKE_TYPE( // + "Real", REAL_TYPE, Text("Real_t"), Text("Real$info"), // + {"divided_by", "Real$divided_by", "func(x,y:Real -> Real)"}, // + {"inverse", "Real$inverse", "func(x:Real -> Real)"}, // + {"minus", "Real$minus", "func(x,y:Real -> Real)"}, // + {"negative", "Real$negative", "func(x:Real -> Real)"}, // + {"plus", "Real$plus", "func(x,y:Real -> Real)"}, // + {"power", "Real$power", "func(base:Real,exponent:Real -> Real)"}, // + {"sqrt", "Real$sqrt", "func(x:Real -> Real)"}, // + {"times", "Real$times", "func(x,y:Real -> Real)"}, // + ), + MAKE_TYPE( // + "CString", Type(CStringType), Text("char*"), Text("CString$info"), // + {"as_text", "Text$from_str", "func(str:CString -> Text)"}, + {"join", "CString$join", "func(glue:CString, pieces:[CString] -> CString)"}), + MAKE_TYPE( // "Path", PATH_TYPE, Text("Path_t"), Text("Path$info"), // {"accessed", "Path$accessed", "func(path:Path, follow_symlinks=yes -> Int64?)"}, // {"append", "Path$append", "func(path:Path, text:Text, permissions=Int32(0o644) -> Result)"}, // @@ -464,8 +475,8 @@ env_t *global_env(bool source_mapping) { {"Int$from_int16", "func(i:Int16 -> Int)"}, // {"Int$from_int32", "func(i:Int32 -> Int)"}, // {"Int$from_int64", "func(i:Int64 -> Int)"}, // - {"Int$from_num64", "func(n:Num, truncate=no -> Int)"}, // - {"Int$from_num32", "func(n:Num32, truncate=no -> Int)"}); + {"Int$from_float64", "func(n:Float64, truncate=no -> Int)"}, // + {"Int$from_float32", "func(n:Float32, truncate=no -> Int)"}); ADD_CONSTRUCTORS("Int64", // {"Int64$from_bool", "func(b:Bool -> Int64)"}, // {"Int64$from_byte", "func(b:Byte -> Int64)"}, // @@ -473,8 +484,8 @@ env_t *global_env(bool source_mapping) { {"Int64$from_int16", "func(i:Int16 -> Int64)"}, // {"Int64$from_int32", "func(i:Int32 -> Int64)"}, // {"Int64$from_int", "func(i:Int, truncate=no -> Int64)"}, // - {"Int64$from_num64", "func(n:Num, truncate=no -> Int64)"}, // - {"Int64$from_num32", "func(n:Num32, truncate=no -> Int64)"}); + {"Int64$from_float64", "func(n:Float64, truncate=no -> Int64)"}, // + {"Int64$from_float32", "func(n:Float32, truncate=no -> Int64)"}); ADD_CONSTRUCTORS("Int32", // {"Int32$from_bool", "func(b:Bool -> Int32)"}, // {"Int32$from_byte", "func(b:Byte -> Int32)"}, // @@ -482,8 +493,8 @@ env_t *global_env(bool source_mapping) { {"Int32$from_int16", "func(i:Int16 -> Int32)"}, // {"Int32$from_int64", "func(i:Int64, truncate=no -> Int32)"}, // {"Int32$from_int", "func(i:Int, truncate=no -> Int32)"}, // - {"Int32$from_num64", "func(n:Num, truncate=no -> Int32)"}, // - {"Int32$from_num32", "func(n:Num32, truncate=no -> Int32)"}); + {"Int32$from_float64", "func(n:Float64, truncate=no -> Int32)"}, // + {"Int32$from_float32", "func(n:Float32, truncate=no -> Int32)"}); ADD_CONSTRUCTORS("Int16", // {"Int16$from_bool", "func(b:Bool -> Int16)"}, // {"Int16$from_byte", "func(b:Byte -> Int16)"}, // @@ -491,8 +502,8 @@ env_t *global_env(bool source_mapping) { {"Int16$from_int32", "func(i:Int32, truncate=no -> Int16)"}, // {"Int16$from_int64", "func(i:Int64, truncate=no -> Int16)"}, // {"Int16$from_int", "func(i:Int, truncate=no -> Int16)"}, // - {"Int16$from_num64", "func(n:Num, truncate=no -> Int16)"}, // - {"Int16$from_num32", "func(n:Num32, truncate=no -> Int16)"}); + {"Int16$from_float64", "func(n:Float64, truncate=no -> Int16)"}, // + {"Int16$from_float32", "func(n:Float32, truncate=no -> Int16)"}); ADD_CONSTRUCTORS("Int8", // {"Int8$from_bool", "func(b:Bool -> Int8)"}, // {"Int8$from_byte", "func(b:Byte -> Int8)"}, // @@ -500,26 +511,26 @@ env_t *global_env(bool source_mapping) { {"Int8$from_int32", "func(i:Int32, truncate=no -> Int8)"}, // {"Int8$from_int64", "func(i:Int64, truncate=no -> Int8)"}, // {"Int8$from_int", "func(i:Int, truncate=no -> Int8)"}, // - {"Int8$from_num64", "func(n:Num, truncate=no -> Int8)"}, // - {"Int8$from_num32", "func(n:Num32, truncate=no -> Int8)"}); - ADD_CONSTRUCTORS("Num", // - {"Num$from_bool", "func(b:Bool -> Num)"}, // - {"Num$from_byte", "func(b:Byte -> Num)"}, // - {"Num$from_int8", "func(i:Int8 -> Num)"}, // - {"Num$from_int16", "func(i:Int16 -> Num)"}, // - {"Num$from_int32", "func(i:Int32 -> Num)"}, // - {"Num$from_int64", "func(i:Int64, truncate=no -> Num)"}, // - {"Num$from_int", "func(i:Int, truncate=no -> Num)"}, // - {"Num$from_num32", "func(n:Num32 -> Num)"}); - ADD_CONSTRUCTORS("Num32", // - {"Num32$from_bool", "func(b:Bool -> Num32)"}, // - {"Num32$from_byte", "func(b:Byte -> Num32)"}, // - {"Num32$from_int8", "func(i:Int8 -> Num32)"}, // - {"Num32$from_int16", "func(i:Int16 -> Num32)"}, // - {"Num32$from_int32", "func(i:Int32, truncate=no -> Num32)"}, // - {"Num32$from_int64", "func(i:Int64, truncate=no -> Num32)"}, // - {"Num32$from_int", "func(i:Int, truncate=no -> Num32)"}, // - {"Num32$from_num64", "func(n:Num -> Num32)"}); + {"Int8$from_float64", "func(n:Float64, truncate=no -> Int8)"}, // + {"Int8$from_float32", "func(n:Float32, truncate=no -> Int8)"}); + ADD_CONSTRUCTORS("Float64", // + {"Float64$from_bool", "func(b:Bool -> Float64)"}, // + {"Float64$from_byte", "func(b:Byte -> Float64)"}, // + {"Float64$from_int8", "func(i:Int8 -> Float64)"}, // + {"Float64$from_int16", "func(i:Int16 -> Float64)"}, // + {"Float64$from_int32", "func(i:Int32 -> Float64)"}, // + {"Float64$from_int64", "func(i:Int64, truncate=no -> Float64)"}, // + {"Float64$from_int", "func(i:Int, truncate=no -> Float64)"}, // + {"Float64$from_float32", "func(n:Float32 -> Float32)"}); + ADD_CONSTRUCTORS("Float32", // + {"Float32$from_bool", "func(b:Bool -> Float32)"}, // + {"Float32$from_byte", "func(b:Byte -> Float32)"}, // + {"Float32$from_int8", "func(i:Int8 -> Float32)"}, // + {"Float32$from_int16", "func(i:Int16 -> Float32)"}, // + {"Float32$from_int32", "func(i:Int32, truncate=no -> Float32)"}, // + {"Float32$from_int64", "func(i:Int64, truncate=no -> Float32)"}, // + {"Float32$from_int", "func(i:Int, truncate=no -> Float32)"}, // + {"Float32$from_float64", "func(n:Float64 -> Float32)"}); ADD_CONSTRUCTORS("Path", // {"Path$escape_text", "func(text:Text -> Path)"}, // {"Path$escape_path", "func(path:Path -> Path)"}, // @@ -545,7 +556,7 @@ env_t *global_env(bool source_mapping) { {"print", "say", "func(text:Text, newline=yes)"}, {"say", "say", "func(text:Text, newline=yes)"}, {"setenv", "setenv_text", "func(name:Text, value:Text?)"}, - {"sleep", "sleep_seconds", "func(seconds:Num)"}, + {"sleep", "sleep_seconds", "func(seconds:Float64)"}, }; for (size_t i = 0; i < sizeof(global_vars) / sizeof(global_vars[0]); i++) { @@ -679,7 +690,8 @@ env_t *get_namespace_by_type(env_t *env, type_t *t) { case BoolType: case IntType: case BigIntType: - case NumType: + case FloatType: + case RealType: case ByteType: { binding_t *b = get_binding(env, Text$as_c_string(type_to_text(t))); assert(b); diff --git a/src/stdlib/README.md b/src/stdlib/README.md index 671d330a..cf375ff6 100644 --- a/src/stdlib/README.md +++ b/src/stdlib/README.md @@ -22,9 +22,9 @@ some common functionality. - C Strings: [c_strings.h](c_strings.h), [c_strings.c](c_strings.c) - Files (used internally only): [files.h](files.h), [files.c](files.c) - Functiontype: [functiontype.h](functiontype.h), [functiontype.c](functiontype.c) -- Integers: [integers.h](integers.h), [integers.c](integers.c) +- Integers: [bigint.h](bigint.h), [bigint.c](bigint.c), [intX.h](intX.h), [intX.c.h](intX.c.h) - Memory: [memory.h](memory.h), [memory.c](memory.c) -- Nums: [nums.h](nums.h), [nums.c](nums.c) +- Floating point numbers: [floatX.h](floatX.h), [floatX.c.h](floatX.c.h) - Optionals: [optionals.h](optionals.h), [optionals.c](optionals.c) - Paths: [paths.h](paths.h), [paths.c](paths.c) - Pointers: [pointers.h](pointers.h), [pointers.c](pointers.c) diff --git a/src/stdlib/bigint.c b/src/stdlib/bigint.c index 8bffbaf1..a1ffc12e 100644 --- a/src/stdlib/bigint.c +++ b/src/stdlib/bigint.c @@ -206,6 +206,7 @@ Int_t Int$slow_divided_by(Int_t dividend, Int_t divisor) { mpz_t quotient, remainder; mpz_init_set_int(quotient, dividend); mpz_init_set_int(remainder, divisor); + if unlikely (mpz_sgn(remainder) == 0) fail("Cannot divide by zero"); mpz_tdiv_qr(quotient, remainder, quotient, remainder); if (mpz_sgn(remainder) < 0) { bool d_positive = likely(divisor.small & 1L) ? divisor.small > 0x1L : mpz_sgn(divisor.big) > 0; @@ -221,6 +222,7 @@ Int_t Int$slow_modulo(Int_t x, Int_t modulus) { mpz_init_set_int(result, x); mpz_t divisor; mpz_init_set_int(divisor, modulus); + if unlikely (mpz_sgn(divisor) == 0) fail("Cannot divide by zero"); mpz_mod(result, result, divisor); return Int$from_mpz(result); } diff --git a/src/stdlib/bigint.h b/src/stdlib/bigint.h index 8c3502bf..a948e1e7 100644 --- a/src/stdlib/bigint.h +++ b/src/stdlib/bigint.h @@ -1,4 +1,5 @@ // Big integer type (`Int` in Tomo) +#pragma once #include <gmp.h> #include <stdbool.h> @@ -102,6 +103,7 @@ MACROLIKE Int_t Int$divided_by(Int_t x, Int_t y) { // https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf const int64_t D = (x.small >> 2L); const int64_t d = (y.small >> 2L); + if unlikely (d == 0) fail("Cannot divide by zero"); int64_t q = D / d, r = D % d; q -= (r < 0L) * (2L * (d > 0L) - 1L); if likely (q == (int32_t)q) return (Int_t){.small = (q << 2L) | 1L}; @@ -115,6 +117,7 @@ MACROLIKE Int_t Int$modulo(Int_t x, Int_t y) { // https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf const int64_t D = (x.small >> 2L); const int64_t d = (y.small >> 2L); + if unlikely (d == 0) fail("Cannot divide by zero"); int64_t r = D % d; r -= (r < 0L) * (2L * (d < 0L) - 1L) * d; return (Int_t){.small = (r << 2L) | 1L}; @@ -136,7 +139,7 @@ MACROLIKE Int_t Int$modulo1(Int_t x, Int_t y) { } MACROLIKE Int_t Int$left_shifted(Int_t x, Int_t y) { - if likely (x.small & y.small & 1L) { + if likely (x.small & y.small & 1L & ((y.small >> 2L) < 30)) { const int64_t z = ((x.small >> 2L) << (y.small >> 2L)) << 2L; if likely (z == (int32_t)z) return (Int_t){.small = z + 1L}; } @@ -189,14 +192,14 @@ MACROLIKE PUREFUNC bool Int$is_negative(Int_t x) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" #endif -MACROLIKE PUREFUNC Int_t Int$from_num64(double n, bool truncate) { +MACROLIKE PUREFUNC Int_t Int$from_float64(double n, bool truncate) { mpz_t result; mpz_init_set_d(result, n); if (!truncate && unlikely(mpz_get_d(result) != n)) fail("Could not convert to an integer without truncation: ", n); return Int$from_mpz(result); } MACROLIKE PUREFUNC Int_t Int$from_num32(float n, bool truncate) { - return Int$from_num64((double)n, truncate); + return Int$from_float64((double)n, truncate); } MACROLIKE Int_t Int$from_int64(int64_t i) { if likely (i >= SMALLEST_SMALL_INT && i <= BIGGEST_SMALL_INT) return (Int_t){.small = (i << 2L) | 1L}; diff --git a/src/stdlib/cli.c b/src/stdlib/cli.c index e30f7ced..50b378a5 100644 --- a/src/stdlib/cli.c +++ b/src/stdlib/cli.c @@ -15,12 +15,13 @@ #include "bytes.h" #include "c_strings.h" #include "cli.h" +#include "floats.h" #include "integers.h" #include "metamethods.h" -#include "nums.h" #include "optionals.h" #include "paths.h" #include "print.h" +#include "reals.h" #include "stdlib.h" #include "tables.h" #include "text.h" @@ -209,14 +210,14 @@ static List_t parse_arg_list(List_t args, const char *flag, void *dest, const Ty if (type->tag == OptionalInfo) { const TypeInfo_t *nonnull = type->OptionalInfo.type; if (streq(arg, "none")) { - if (nonnull == &Num$info) *(double *)dest = (double)NAN; - else if (nonnull == &Num32$info) *(float *)dest = (float)NAN; + if (nonnull == &Float64$info) *(double *)dest = (double)NAN; + else if (nonnull == &Float32$info) *(float *)dest = (float)NAN; else memset(dest, 0, (size_t)type->size); return List$from(args, I(2)); } else { args = parse_arg_list(args, flag, dest, nonnull, allow_dashes); - if (nonnull == &Int$info || nonnull == &Path$info || nonnull == &Num$info || nonnull == &Num32$info - || nonnull->tag == TextInfo || nonnull->tag == EnumInfo) + if (nonnull == &Int$info || nonnull == &Path$info || nonnull == &Float64$info || nonnull == &Float32$info + || nonnull == &Real$info || nonnull->tag == TextInfo || nonnull->tag == EnumInfo) return args; else if (nonnull == &Int64$info) ((OptionalInt64_t *)dest)->has_value = true; else if (nonnull == &Int32$info) ((OptionalInt32_t *)dest)->has_value = true; @@ -261,14 +262,14 @@ static List_t parse_arg_list(List_t args, const char *flag, void *dest, const Ty OptionalBool_t parsed = Bool$parse(Text$from_str(arg), NULL); if (parsed == NONE_BOOL) print_err("Could not parse argument for ", flag, ": ", arg); *(Bool_t *)dest = parsed; - } else if (type == &Num$info) { - OptionalNum_t parsed = Num$parse(Text$from_str(arg), NULL); + } else if (type == &Float64$info) { + OptionalFloat64_t parsed = Float64$parse(Text$from_str(arg), NULL); if (isnan(parsed)) print_err("Could not parse argument for ", flag, ": ", arg); - *(Num_t *)dest = parsed; - } else if (type == &Num32$info) { - OptionalNum32_t parsed = Num32$parse(Text$from_str(arg), NULL); + *(Float64_t *)dest = parsed; + } else if (type == &Float32$info) { + OptionalFloat32_t parsed = Float32$parse(Text$from_str(arg), NULL); if (isnan(parsed)) print_err("Could not parse argument for ", flag, ": ", arg); - *(Num32_t *)dest = parsed; + *(Float32_t *)dest = parsed; } else if (type->tag == PointerInfo) { // For pointers, we can just allocate memory for the value and then parse the value void *value = GC_MALLOC((size_t)type->PointerInfo.pointed->size); diff --git a/src/stdlib/datatypes.h b/src/stdlib/datatypes.h index 3cd99f38..04e12d97 100644 --- a/src/stdlib/datatypes.h +++ b/src/stdlib/datatypes.h @@ -18,8 +18,8 @@ #define LIST_MAX_DATA_REFCOUNT MAX_FOR_N_BITS(LIST_REFCOUNT_BITS) #define LIST_MAX_FREE_ENTRIES MAX_FOR_N_BITS(LIST_FREE_BITS) -#define Num_t double -#define Num32_t float +#define Float64_t double +#define Float32_t float #define Int64_t int64_t #define Int32_t int32_t @@ -35,6 +35,23 @@ typedef union { #define OptionalInt_t Int_t +typedef struct Real_s *Real_t; + +struct Real_s { + // Compute floor(real*10^n) + Int_t (*compute)(Real_t, int64_t); + union { + double n; + Int_t i; + struct Real_s *children; + } userdata; + Int_t approximation; + bool exact : 1; + int64_t approximation_decimals : 63; +}; + +#define OptionalReal_t Real_t + typedef struct { void *data; // All of the following fields add up to 64 bits, which means that list diff --git a/src/stdlib/float32.c b/src/stdlib/float32.c new file mode 100644 index 00000000..855118ba --- /dev/null +++ b/src/stdlib/float32.c @@ -0,0 +1,4 @@ +// Type infos and methods for Float32 (32-bit floating point) using a template file + +#define FLOATX_C_H__BITS 32 +#include "floatX.c.h" diff --git a/src/stdlib/float64.c b/src/stdlib/float64.c new file mode 100644 index 00000000..e41c01f5 --- /dev/null +++ b/src/stdlib/float64.c @@ -0,0 +1,4 @@ +// Type infos and methods for Float64 (64-bit floating point) using a template file + +#define FLOATX_C_H__BITS 64 +#include "floatX.c.h" diff --git a/src/stdlib/numX.c.h b/src/stdlib/floatX.c.h index 22db3ca3..cfef29fd 100644 --- a/src/stdlib/numX.c.h +++ b/src/stdlib/floatX.c.h @@ -1,8 +1,8 @@ -// Type infos and methods for Nums (floating point) -// This file is a template that expects `NUMSX_C_H__BITS` to be defined before including: +// Type infos and methods for Floats (floating point numbers) +// This file is a template that expects `FLOATX_C_H__BITS` to be defined before including: // -// #define NUMX_C_H__BITS 64 -// #include "numX.c.h" +// #define FLOATX_C_H__BITS 64 +// #include "floatX.c.h" // #include <float.h> #include <gc.h> @@ -14,32 +14,32 @@ #include "text.h" #include "types.h" -#ifndef NUMX_C_H__BITS -#define NUMX_C_H__BITS 64 +#ifndef FLOATX_C_H__BITS +#define FLOATX_C_H__BITS 64 #endif -#if NUMX_C_H__BITS == 64 -#define NUM_T double +#if FLOATX_C_H__BITS == 64 +#define FLOAT_T double #define OPT_T double -#define NAMESPACED(x) Num$##x -#define TYPE_STR "Num" +#define NAMESPACED(x) Float64$##x +#define TYPE_STR "Float64" #define SUFFIXED(x) x -#elif NUMX_C_H__BITS == 32 -#define NUM_T float +#elif FLOATX_C_H__BITS == 32 +#define FLOAT_T float #define OPT_T float -#define NAMESPACED(x) Num32$##x -#define TYPE_STR "Num32" +#define NAMESPACED(x) Float32$##x +#define TYPE_STR "Float32" #define SUFFIXED(x) x##f #else -#error "Unsupported bit width for Num" +#error "Unsupported bit width for Float" #endif -#if NUMX_C_H__BITS == 64 +#if FLOATX_C_H__BITS == 64 #include "fpconv.h" #include "string.h" public -PUREFUNC Text_t NAMESPACED(value_as_text)(NUM_T x) { +PUREFUNC Text_t NAMESPACED(value_as_text)(FLOAT_T x) { char *str = GC_MALLOC_ATOMIC(24); int len = fpconv_dtoa(x, str); return Text$from_strn(str, (size_t)len); @@ -49,7 +49,7 @@ PUREFUNC Text_t NAMESPACED(as_text)(const void *x, bool colorize, const TypeInfo (void)info; if (!x) return Text(TYPE_STR); static const Text_t color_prefix = Text("\x1b[35m"), color_suffix = Text("\x1b[m"); - Text_t text = NAMESPACED(value_as_text)(*(NUM_T *)x); + Text_t text = NAMESPACED(value_as_text)(*(FLOAT_T *)x); return colorize ? Text$concat(color_prefix, text, color_suffix) : text; } public @@ -64,18 +64,18 @@ PUREFUNC int32_t NAMESPACED(compare)(const void *x, const void *y, const TypeInf return (rx > ry) - (rx < ry); } -#elif NUMX_C_H__BITS == 32 +#elif FLOATX_C_H__BITS == 32 public -PUREFUNC Text_t NAMESPACED(value_as_text)(NUM_T x) { - return Num$value_as_text((double)x); +PUREFUNC Text_t NAMESPACED(value_as_text)(FLOAT_T x) { + return Float64$value_as_text((double)x); } public PUREFUNC Text_t NAMESPACED(as_text)(const void *x, bool colorize, const TypeInfo_t *info) { (void)info; if (!x) return Text(TYPE_STR); static const Text_t color_prefix = Text("\x1b[35m"), color_suffix = Text("\x1b[m"); - Text_t text = Num$value_as_text((double)*(NUM_T *)x); - return colorize ? Text$concat(color_prefix, text, color_suffix) : text; + Text_t text = Float64$value_as_text((double)*(FLOAT_T *)x); + return colorize ? Texts(color_prefix, text, color_suffix) : text; } public PUREFUNC int32_t NAMESPACED(compare)(const void *x, const void *y, const TypeInfo_t *info) { @@ -94,71 +94,71 @@ PUREFUNC int32_t NAMESPACED(compare)(const void *x, const void *y, const TypeInf public PUREFUNC bool NAMESPACED(equal)(const void *x, const void *y, const TypeInfo_t *info) { (void)info; - return *(NUM_T *)x == *(NUM_T *)y; + return *(FLOAT_T *)x == *(FLOAT_T *)y; } public -CONSTFUNC bool NAMESPACED(near)(NUM_T a, NUM_T b, NUM_T ratio, NUM_T absolute) { +CONSTFUNC bool NAMESPACED(near)(FLOAT_T a, FLOAT_T b, FLOAT_T ratio, FLOAT_T absolute) { if (ratio < 0) ratio = 0; else if (ratio > 1) ratio = 1; if (a == b) return true; - NUM_T diff = SUFFIXED(fabs)(a - b); + FLOAT_T diff = SUFFIXED(fabs)(a - b); if (diff < absolute) return true; else if (isnan(diff)) return false; - NUM_T epsilon = SUFFIXED(fabs)(a * ratio) + SUFFIXED(fabs)(b * ratio); + FLOAT_T epsilon = SUFFIXED(fabs)(a * ratio) + SUFFIXED(fabs)(b * ratio); if (isinf(epsilon)) epsilon = DBL_MAX; return (diff < epsilon); } public -Text_t NAMESPACED(percent)(NUM_T x, NUM_T precision) { - NUM_T d = SUFFIXED(100.) * x; +Text_t NAMESPACED(percent)(FLOAT_T x, FLOAT_T precision) { + FLOAT_T d = SUFFIXED(100.) * x; d = NAMESPACED(with_precision)(d, precision); return Text$concat(NAMESPACED(value_as_text)(d), Text("%")); } public -CONSTFUNC NUM_T NAMESPACED(with_precision)(NUM_T num, NUM_T precision) { - if (precision == SUFFIXED(0.0)) return num; +CONSTFUNC FLOAT_T NAMESPACED(with_precision)(FLOAT_T n, FLOAT_T precision) { + if (precision == SUFFIXED(0.0)) return n; // Precision will be, e.g. 0.01 or 100. if (precision < SUFFIXED(1.)) { - NUM_T inv = SUFFIXED(round)(SUFFIXED(1.) / precision); // Necessary to make the math work - NUM_T k = num * inv; + FLOAT_T inv = SUFFIXED(round)(SUFFIXED(1.) / precision); // Necessary to make the math work + FLOAT_T k = n * inv; return SUFFIXED(round)(k) / inv; } else { - NUM_T k = num / precision; + FLOAT_T k = n / precision; return SUFFIXED(round)(k) * precision; } } public -CONSTFUNC NUM_T NAMESPACED(mod)(NUM_T num, NUM_T modulus) { +CONSTFUNC FLOAT_T NAMESPACED(mod)(FLOAT_T n, FLOAT_T modulus) { // Euclidean division, see: // https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf - NUM_T r = (NUM_T)remainder((double)num, (double)modulus); + FLOAT_T r = (FLOAT_T)remainder((double)n, (double)modulus); r -= (r < SUFFIXED(0.)) * (SUFFIXED(2.) * (modulus < SUFFIXED(0.)) - SUFFIXED(1.)) * modulus; return r; } public -CONSTFUNC NUM_T NAMESPACED(mod1)(NUM_T num, NUM_T modulus) { - return SUFFIXED(1.0) + NAMESPACED(mod)(num - SUFFIXED(1.0), modulus); +CONSTFUNC FLOAT_T NAMESPACED(mod1)(FLOAT_T n, FLOAT_T modulus) { + return SUFFIXED(1.0) + NAMESPACED(mod)(n - SUFFIXED(1.0), modulus); } public -CONSTFUNC NUM_T NAMESPACED(mix)(NUM_T amount, NUM_T x, NUM_T y) { +CONSTFUNC FLOAT_T NAMESPACED(mix)(FLOAT_T amount, FLOAT_T x, FLOAT_T y) { return (SUFFIXED(1.0) - amount) * x + amount * y; } public -CONSTFUNC bool NAMESPACED(is_between)(const NUM_T x, const NUM_T low, const NUM_T high) { - return (low <= x && x <= high) || (high <= x && x <= low); +CONSTFUNC bool NAMESPACED(is_between)(const FLOAT_T x, const FLOAT_T low, const FLOAT_T high) { + return low <= x && x <= high; } public -CONSTFUNC NUM_T NAMESPACED(clamped)(NUM_T x, NUM_T low, NUM_T high) { +CONSTFUNC FLOAT_T NAMESPACED(clamped)(FLOAT_T x, FLOAT_T low, FLOAT_T high) { return (x <= low) ? low : (x >= high ? high : x); } @@ -166,10 +166,10 @@ public OPT_T NAMESPACED(parse)(Text_t text, Text_t *remainder) { const char *str = Text$as_c_string(text); char *end = NULL; -#if NUMX_C_H__BITS == 64 - NUM_T n = strtod(str, &end); -#elif NUMX_C_H__BITS == 32 - NUM_T n = strtof(str, &end); +#if FLOATX_C_H__BITS == 64 + FLOAT_T n = strtod(str, &end); +#elif FLOATX_C_H__BITS == 32 + FLOAT_T n = strtof(str, &end); #endif if (end > str) { if (remainder) *remainder = Text$from_str(end); @@ -184,26 +184,26 @@ OPT_T NAMESPACED(parse)(Text_t text, Text_t *remainder) { public CONSTFUNC bool NAMESPACED(is_none)(const void *n, const TypeInfo_t *info) { (void)info; - return isnan(*(NUM_T *)n); + return isnan(*(FLOAT_T *)n); } public -CONSTFUNC bool NAMESPACED(isinf)(NUM_T n) { +CONSTFUNC bool NAMESPACED(isinf)(FLOAT_T n) { return (fpclassify(n) == FP_INFINITE); } public -CONSTFUNC bool NAMESPACED(finite)(NUM_T n) { +CONSTFUNC bool NAMESPACED(finite)(FLOAT_T n) { return (fpclassify(n) != FP_INFINITE); } public -CONSTFUNC bool NAMESPACED(isnan)(NUM_T n) { +CONSTFUNC bool NAMESPACED(isnan)(FLOAT_T n) { return (fpclassify(n) == FP_NAN); } public const TypeInfo_t NAMESPACED(info) = { - .size = sizeof(NUM_T), - .align = __alignof__(NUM_T), + .size = sizeof(FLOAT_T), + .align = __alignof__(FLOAT_T), .metamethods = { .compare = NAMESPACED(compare), @@ -213,9 +213,9 @@ const TypeInfo_t NAMESPACED(info) = { }, }; -#undef NUM_T +#undef FLOAT_T #undef OPT_T #undef NAMESPACED #undef TYPE_STR #undef SUFFIXED -#undef NUMX_C_H__BITS +#undef FLOATX_C_H__BITS diff --git a/src/stdlib/floatX.h b/src/stdlib/floatX.h new file mode 100644 index 00000000..ff2d0931 --- /dev/null +++ b/src/stdlib/floatX.h @@ -0,0 +1,103 @@ +// Template header for 64 and 32 bit floating point numbers +// This file expects `FLOATX_H__BITS` to be defined before including: +// +// #define FLOATX_H__BITS 64 +// #include "floatX.h" +// + +#include <stdbool.h> +#include <stdint.h> + +#include "datatypes.h" +#include "stdlib.h" +#include "types.h" +#include "util.h" + +#ifndef FLOATX_H__BITS +#define FLOATX_H__BITS 64 +#endif + +#if FLOATX_H__BITS == 64 +#define FLOAT_T double +#define OPT_T double +#define NAMESPACED(x) Float64$##x +#define TYPE_STR "Float64" +#define SUFFIXED(x) x +#elif FLOATX_H__BITS == 32 +#define FLOAT_T float +#define OPT_T float +#define NAMESPACED(x) Float32$##x +#define TYPE_STR "Float32" +#define SUFFIXED(x) x##f +#else +#error "Unsupported bit width for Float" +#endif + +Text_t NAMESPACED(as_text)(const void *x, bool colorize, const TypeInfo_t *type); +Text_t NAMESPACED(value_as_text)(FLOAT_T x); +PUREFUNC int32_t NAMESPACED(compare)(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool NAMESPACED(equal)(const void *x, const void *y, const TypeInfo_t *type); +CONSTFUNC bool NAMESPACED(near)(FLOAT_T a, FLOAT_T b, FLOAT_T ratio, FLOAT_T absolute); +Text_t NAMESPACED(percent)(FLOAT_T x, FLOAT_T precision); +FLOAT_T CONSTFUNC NAMESPACED(with_precision)(FLOAT_T n, FLOAT_T precision); +FLOAT_T NAMESPACED(mod)(FLOAT_T n, FLOAT_T modulus); +FLOAT_T NAMESPACED(mod1)(FLOAT_T n, FLOAT_T modulus); +CONSTFUNC bool NAMESPACED(isinf)(FLOAT_T n); +CONSTFUNC bool NAMESPACED(finite)(FLOAT_T n); +CONSTFUNC bool NAMESPACED(isnan)(FLOAT_T n); +bool NAMESPACED(is_none)(const void *n, const TypeInfo_t *info); +FLOAT_T NAMESPACED(nan)(Text_t tag); +CONSTFUNC FLOAT_T NAMESPACED(mix)(FLOAT_T amount, FLOAT_T x, FLOAT_T y); +OPT_T NAMESPACED(parse)(Text_t text, Text_t *remainder); +CONSTFUNC bool NAMESPACED(is_between)(const FLOAT_T x, const FLOAT_T low, const FLOAT_T high); +CONSTFUNC FLOAT_T NAMESPACED(clamped)(FLOAT_T x, FLOAT_T low, FLOAT_T high); + +#if FLOATX_H__BITS == 64 +MACROLIKE CONSTFUNC FLOAT_T NAMESPACED(from_float32)(float n) { return (FLOAT_T)n; } +#elif FLOATX_H__BITS == 32 +MACROLIKE CONSTFUNC FLOAT_T NAMESPACED(from_float64)(double n) { return (FLOAT_T)n; } +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif +MACROLIKE CONSTFUNC FLOAT_T NAMESPACED(from_int)(Int_t i, bool truncate) { + if likely (i.small & 0x1) { + FLOAT_T ret = (FLOAT_T)(i.small >> 2); + if unlikely (!truncate && (int64_t)ret != (i.small >> 2)) + fail("Could not convert integer to " TYPE_STR " without losing precision: ", i.small >> 2); + return ret; + } else { + FLOAT_T ret = mpz_get_d(i.big); + if (!truncate) { + mpz_t roundtrip; + mpz_init_set_d(roundtrip, (double)ret); + if unlikely (mpz_cmp(i.big, roundtrip) != 0) + fail("Could not convert integer to " TYPE_STR " without losing precision: ", i); + } + return ret; + } +} +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif +MACROLIKE CONSTFUNC FLOAT_T NAMESPACED(from_int64)(Int64_t i, bool truncate) { + FLOAT_T n = (FLOAT_T)i; + if unlikely (!truncate && (Int64_t)n != i) + fail("Could not convert integer to " TYPE_STR " without losing precision: ", i); + return n; +} +MACROLIKE CONSTFUNC FLOAT_T NAMESPACED(from_int32)(Int32_t i) { return (FLOAT_T)i; } +MACROLIKE CONSTFUNC FLOAT_T NAMESPACED(from_int16)(Int16_t i) { return (FLOAT_T)i; } +MACROLIKE CONSTFUNC FLOAT_T NAMESPACED(from_int8)(Int8_t i) { return (FLOAT_T)i; } +MACROLIKE CONSTFUNC FLOAT_T NAMESPACED(from_byte)(Byte_t i) { return (FLOAT_T)i; } + +extern const TypeInfo_t NAMESPACED(info); + +#undef FLOAT_T +#undef OPT_T +#undef NAMESPACED +#undef TYPE_STR +#undef SUFFIXED +#undef FLOATX_H__BITS diff --git a/src/stdlib/floats.h b/src/stdlib/floats.h new file mode 100644 index 00000000..c23974c1 --- /dev/null +++ b/src/stdlib/floats.h @@ -0,0 +1,13 @@ +// Type infos and methods for Floats (floating point numbers) + +#pragma once + +#define F64(n) ((double)(n)) +#define OptionalFloat64_t double +#define FLOATX_H__BITS 64 +#include "floatX.h" + +#define F32(n) ((float)(n)) +#define OptionalFloat32_t float +#define FLOATX_H__BITS 32 +#include "floatX.h" diff --git a/src/stdlib/intX.h b/src/stdlib/intX.h index 3c4fa976..c90babcb 100644 --- a/src/stdlib/intX.h +++ b/src/stdlib/intX.h @@ -102,16 +102,17 @@ MACROLIKE PUREFUNC INTX_T NAMESPACED(unsigned_right_shifted)(INTX_T x, INTX_T y) void NAMESPACED(serialize)(const void *obj, FILE *out, Table_t *, const TypeInfo_t *); void NAMESPACED(deserialize)(FILE *in, void *outval, List_t *, const TypeInfo_t *); -MACROLIKE PUREFUNC INTX_T NAMESPACED(from_num64)(Num_t n, bool truncate) { +MACROLIKE PUREFUNC INTX_T NAMESPACED(from_float64)(Float64_t n, bool truncate) { INTX_T i = (INTX_T)n; - if (!truncate && unlikely((Num_t)i != n)) fail("Could not convert Num to an " NAME_STR " without truncation: ", n); + if (!truncate && unlikely((Float64_t)i != n)) + fail("Could not convert Float64 to an " NAME_STR " without truncation: ", n); return i; } -MACROLIKE PUREFUNC INTX_T NAMESPACED(from_num32)(Num32_t n, bool truncate) { +MACROLIKE PUREFUNC INTX_T NAMESPACED(from_float32)(Float32_t n, bool truncate) { INTX_T i = (INTX_T)n; - if (!truncate && unlikely((Num32_t)i != n)) - fail("Could not convert Num32 to an " NAME_STR " without truncation: ", n); + if (!truncate && unlikely((Float32_t)i != n)) + fail("Could not convert Float32 to an " NAME_STR " without truncation: ", n); return i; } diff --git a/src/stdlib/lists.c b/src/stdlib/lists.c index 9753cd86..93dc63e9 100644 --- a/src/stdlib/lists.c +++ b/src/stdlib/lists.c @@ -345,18 +345,18 @@ Table_t List$counts(List_t list, const TypeInfo_t *type) { return counts; } -static double _default_random_num(void *userdata) { +static double _default_random_float64(void *userdata) { (void)userdata; union { - Num_t num; + Float64_t n; uint64_t bits; - } r = {.bits = 0}, one = {.num = 1.0}; + } r = {.bits = 0}, one = {.n = 1.0}; assert(getrandom((uint8_t *)&r, sizeof(r), 0) == sizeof(r)); - // Set r.num to 1.<random-bits> + // Set r.n to 1.<random-bits> r.bits &= ~(0xFFFULL << 52); r.bits |= (one.bits & (0xFFFULL << 52)); - return r.num - 1.0; + return r.n - 1.0; } public @@ -419,7 +419,7 @@ List_t List$sample(List_t list, Int_t int_n, List_t weights, OptionalClosure_t r if (aliases[i].alias == -1) aliases[i].alias = i; typedef double (*rng_fn_t)(void *); - rng_fn_t rng_fn = random_num.fn ? (rng_fn_t)random_num.fn : _default_random_num; + rng_fn_t rng_fn = random_num.fn ? (rng_fn_t)random_num.fn : _default_random_float64; List_t selected = {.data = list.atomic ? GC_MALLOC_ATOMIC((size_t)(n * padded_item_size)) : GC_MALLOC((size_t)(n * padded_item_size)), diff --git a/src/stdlib/num32.c b/src/stdlib/num32.c deleted file mode 100644 index 6d505f37..00000000 --- a/src/stdlib/num32.c +++ /dev/null @@ -1,4 +0,0 @@ -// Type infos and methods for Num32 (32-bit floating point) using a template file - -#define NUMX_C_H__BITS 32 -#include "numX.c.h" diff --git a/src/stdlib/num64.c b/src/stdlib/num64.c deleted file mode 100644 index 7fdc8f35..00000000 --- a/src/stdlib/num64.c +++ /dev/null @@ -1,4 +0,0 @@ -// Type infos and methods for Num (64-bit floating point) using a template file - -#define NUMX_C_H__BITS 64 -#include "numX.c.h" diff --git a/src/stdlib/nums.h b/src/stdlib/nums.h deleted file mode 100644 index 8cea9e84..00000000 --- a/src/stdlib/nums.h +++ /dev/null @@ -1,13 +0,0 @@ -// Type infos and methods for Nums (floating point) - -#pragma once - -#define N64(n) ((double)(n)) -#define OptionalNum_t double -#define NUMX_H__BITS 64 -#include "numX.h" - -#define N32(n) ((float)(n)) -#define OptionalNum32_t float -#define NUMX_H__BITS 32 -#include "numX.h" diff --git a/src/stdlib/optionals.c b/src/stdlib/optionals.c index 3fe812b1..b2cd584d 100644 --- a/src/stdlib/optionals.c +++ b/src/stdlib/optionals.c @@ -3,8 +3,8 @@ #include <math.h> #include "datatypes.h" +#include "floats.h" #include "metamethods.h" -#include "nums.h" #include "optionals.h" #include "text.h" #include "util.h" @@ -66,8 +66,8 @@ void Optional$deserialize(FILE *in, void *outval, List_t *pointers, const TypeIn if (nonnull->tag == TextInfo) *(Text_t *)outval = NONE_TEXT; else if (nonnull->tag == ListInfo) *(List_t *)outval = NONE_LIST; else if (nonnull->tag == TableInfo) *(Table_t *)outval = NONE_TABLE; - else if (nonnull == &Num$info) *(double *)outval = (double)NAN; - else if (nonnull == &Num32$info) *(float *)outval = (float)NAN; + else if (nonnull == &Float64$info) *(double *)outval = (double)NAN; + else if (nonnull == &Float32$info) *(float *)outval = (float)NAN; else if (nonnull->tag == StructInfo || (nonnull->tag == OpaqueInfo && type->size > nonnull->size)) memset(outval + type->size, -1, (size_t)(type->size - nonnull->size)); else memset(outval, 0, (size_t)type->size); diff --git a/src/stdlib/print.c b/src/stdlib/print.c index 7da1343f..5d90d6c3 100644 --- a/src/stdlib/print.c +++ b/src/stdlib/print.c @@ -7,13 +7,16 @@ #include "fpconv.h" #include "print.h" +#include "reals.h" #include "util.h" public int _print_int(FILE *f, int64_t n) { + if (n == 0) return fputc('0', f); char buf[21] = {[20] = 0}; // Big enough for INT64_MIN + '\0' char *p = &buf[19]; bool negative = n < 0; + if (negative) n = -n; do { *(p--) = '0' + (n % 10); @@ -93,6 +96,9 @@ int _print_double(FILE *f, double n) { } public +int _print_real(FILE *f, Real_t n) { return Text$print(f, Real$value_as_text(n, 10)); } + +public int _print_hex_double(FILE *f, hex_double_t hex) { if (hex.d != hex.d) return fputs("NAN", f); else if (hex.d == 1.0 / 0.0) return fputs("INF", f); diff --git a/src/stdlib/print.h b/src/stdlib/print.h index 943a084a..0837390f 100644 --- a/src/stdlib/print.h +++ b/src/stdlib/print.h @@ -77,6 +77,7 @@ typedef struct { int _print_int(FILE *f, int64_t x); int _print_uint(FILE *f, uint64_t x); int _print_double(FILE *f, double x); +int _print_real(FILE *f, Real_t x); int _print_hex(FILE *f, hex_format_t hex); int _print_hex_double(FILE *f, hex_double_t hex); int _print_oct(FILE *f, oct_format_t oct); @@ -124,6 +125,7 @@ extern int Int$print(FILE *f, Int_t i); uint8_t: _print_uint, \ float: _print_float, \ double: _print_double, \ + Real_t: _print_real, \ hex_format_t: _print_hex, \ hex_double_t: _print_hex_double, \ oct_format_t: _print_oct, \ diff --git a/src/stdlib/reals.c b/src/stdlib/reals.c new file mode 100644 index 00000000..56f247ff --- /dev/null +++ b/src/stdlib/reals.c @@ -0,0 +1,312 @@ +#include <gc.h> +#include <gmp.h> +#include <math.h> +#include <stdbool.h> +#include <stdint.h> + +#include "bigint.h" +#include "datatypes.h" +#include "reals.h" +#include "text.h" +#include "types.h" + +struct ieee754_bits { + bool negative : 1; + uint64_t biased_exponent : 11; + uint64_t fraction : 53; +}; + +static inline Int_t pow10(Int_t x, int64_t n) { + if (n == 0) return x; + else if (n < 0) return Int$divided_by(x, Int$power(I(10), I(-n))); + else return Int$times(x, Int$power(I(10), I(n))); +} + +public +Int_t Real$compute(Real_t r, int64_t decimals) { + if (r->approximation.small != 0 && r->approximation_decimals >= decimals) { + return r->approximation_decimals == decimals ? r->approximation + : pow10(r->approximation, decimals - r->approximation_decimals); + } + + r->approximation = r->compute(r, decimals); + r->approximation_decimals = decimals; + return r->approximation; +} + +static int64_t approx_log10(Real_t r, int64_t decimals) { + if ((r->approximation.small | 0x1) == 0x1) { + (void)Real$compute(r, decimals); + } + + if ((r->approximation.small & 0x1) == 0x1) { + int64_t small = (r->approximation.small) >> 2; + if (small < 0) small = -small; + int64_t leading_zeroes = (int64_t)__builtin_clzl((uint64_t)labs(small)); + return (64 - leading_zeroes) + r->approximation_decimals; + } else { + size_t digits = mpz_sizeinbase(r->approximation.big, 10); + return (int64_t)digits + r->approximation_decimals; + } +} + +static Int_t Real$compute_int(Real_t r, int64_t decimals) { return pow10(r->userdata.i, decimals); } + +static Int_t Real$compute_double(Real_t r, int64_t decimals) { + // TODO: this is probably inaccurate + return Int$from_float64(r->userdata.n * pow(10, (double)decimals), true); +} + +public +OptionalReal_t Real$parse(Text_t text, Text_t *remainder) { + Text_t decimal_onwards = EMPTY_TEXT; + OptionalInt_t int_component = Int$parse(text, I(10), &decimal_onwards); + if (int_component.small == 0) int_component = I(0); + Text_t fraction_text = EMPTY_TEXT; + if (Text$starts_with(decimal_onwards, Text("."), &fraction_text)) { + fraction_text = Text$replace(fraction_text, Text("_"), EMPTY_TEXT); + OptionalInt_t fraction; + if (fraction_text.length == 0) { + fraction = I(0); + } else { + fraction = Int$parse(fraction_text, I(10), remainder); + if (fraction.small == 0) return NONE_REAL; + } + int64_t shift = fraction_text.length; + Int_t scale = Int$power(I(10), I(shift)); + Int_t i = Int$plus(Int$times(int_component, scale), fraction); + Real_t ret = Real$divided_by(Real$from_int(i), Real$from_int(scale)); + ret->approximation = i; + ret->approximation_decimals = shift; + return ret; + } else { + if (decimal_onwards.length > 0) { + if (remainder) *remainder = decimal_onwards; + else return NONE_REAL; + } + return Real$from_int(int_component); + } +} + +public +Real_t Real$from_float64(double n) { return new (struct Real_s, .compute = Real$compute_double, .userdata.n = n); } + +public +double Real$as_float64(Real_t x) { + int64_t decimals = 17; + Int_t i = Real$compute(x, decimals); + mpq_t q; + mpz_t num; + mpz_init_set_int(num, i); + mpz_t den; + mpz_init_set_int(den, Int$power(I(10), I(decimals))); + mpq_set_num(q, num); + mpq_set_den(q, den); + return mpq_get_d(q); +} + +public +Real_t Real$from_int(Int_t i) { + return new (struct Real_s, .compute = Real$compute_int, .userdata.i = i, .approximation = i, .exact = 1, + .approximation_decimals = 0); +} + +static Int_t Real$compute_negative(Real_t r, int64_t decimals) { + Int_t x = Real$compute(&r->userdata.children[0], decimals); + return Int$negative(x); +} + +public +Real_t Real$negative(Real_t x) { return new (struct Real_s, .compute = Real$compute_negative, .userdata.children = x); } + +static Int_t Real$compute_plus(Real_t r, int64_t decimals) { + Int_t lhs = Real$compute(&r->userdata.children[0], decimals + 1); + Int_t rhs = Real$compute(&r->userdata.children[1], decimals + 1); + return Int$divided_by(Int$plus(lhs, rhs), I(10)); +} + +public +Real_t Real$plus(Real_t x, Real_t y) { + Real_t result = + new (struct Real_s, .compute = Real$compute_plus, .userdata.children = GC_MALLOC(sizeof(struct Real_s[2])), ); + result->userdata.children[0] = *x; + result->userdata.children[1] = *y; + return result; +} + +static Int_t Real$compute_minus(Real_t r, int64_t decimals) { + Int_t lhs = Real$compute(&r->userdata.children[0], decimals + 1); + Int_t rhs = Real$compute(&r->userdata.children[1], decimals + 1); + return Int$divided_by(Int$minus(lhs, rhs), I(10)); +} + +public +Real_t Real$minus(Real_t x, Real_t y) { + Real_t result = + new (struct Real_s, .compute = Real$compute_minus, .userdata.children = GC_MALLOC(sizeof(struct Real_s[2])), ); + result->userdata.children[0] = *x; + result->userdata.children[1] = *y; + return result; +} + +static Int_t Real$compute_times(Real_t r, int64_t decimals) { + Real_t lhs = &r->userdata.children[0]; + Real_t rhs = &r->userdata.children[1]; + + int64_t half_prec = decimals / 2; + + int64_t lhs_decimals = approx_log10(lhs, half_prec); + int64_t rhs_decimals = approx_log10(rhs, half_prec); + + Real_t big, small; + if (lhs_decimals >= rhs_decimals) big = lhs, small = rhs; + else big = rhs, small = lhs; + + Int_t approx_small = Real$compute(small, decimals - MAX(lhs_decimals, rhs_decimals) - 3); + if (approx_small.small == 0x1) return I(0); + + Int_t approx_big = Real$compute(big, decimals - MIN(lhs_decimals, rhs_decimals) - 3); + if (approx_big.small == 0x1) return I(0); + + return Int$right_shifted(Int$times(approx_big, approx_small), + Int$from_int64(lhs_decimals + rhs_decimals - decimals)); +} + +public +Real_t Real$times(Real_t x, Real_t y) { + // Simplification rules: + if (x->compute == Real$compute_int && y->compute == Real$compute_int) { + return Real$from_int(Int$times(x->userdata.i, y->userdata.i)); + } else if (x->compute == Real$compute_times && y->compute == Real$compute_int) { + if (x->userdata.children[0].compute == Real$compute_int) + return Real$times(Real$times(&x->userdata.children[0], y), &x->userdata.children[1]); + else if (x->userdata.children[1].compute == Real$compute_int) + return Real$times(Real$times(&x->userdata.children[1], y), &x->userdata.children[0]); + } + + Real_t result = + new (struct Real_s, .compute = Real$compute_times, .userdata.children = GC_MALLOC(sizeof(struct Real_s[2]))); + + result->userdata.children[0] = *x; + result->userdata.children[1] = *y; + return result; +} + +static Int_t Real$compute_divided_by(Real_t r, int64_t decimals) { + int64_t den_mag = approx_log10(&r->userdata.children[1], 100); + Int_t num = Real$compute(&r->userdata.children[0], decimals * 2 - den_mag); + Int_t den = Real$compute(&r->userdata.children[1], decimals - den_mag); + return Int$divided_by(num, den); +} + +public +Real_t Real$divided_by(Real_t x, Real_t y) { + // Exact integer division: + if (x->compute == Real$compute_int && y->compute == Real$compute_int) { + Int_t int_result = Int$divided_by(x->userdata.i, y->userdata.i); + if (Int$equal_value(x->userdata.i, Int$times(int_result, y->userdata.i))) { + return Real$from_int(int_result); + } + } + Real_t result = new (struct Real_s, .compute = Real$compute_divided_by, + .userdata.children = GC_MALLOC(sizeof(struct Real_s[2])), ); + result->userdata.children[0] = *x; + result->userdata.children[1] = *y; + return result; +} + +static Int_t Real$compute_sqrt(Real_t r, int64_t decimals) { + Real_t operand = r->userdata.children; + double d = Real$as_float64(operand); + // TODO: newton's method to iterate + return Int$from_float64(sqrt(d) * pow(10.0, (double)decimals), true); +} + +public +Real_t Real$sqrt(Real_t x) { return new (struct Real_s, .compute = Real$compute_sqrt, .userdata.children = x); } + +public +Text_t Real$value_as_text(Real_t x, int64_t digits) { + Int_t scaled_int = Real$compute(x, digits); + Text_t scaled_string = Int$value_as_text(Int$abs(scaled_int)); + Text_t result; + if (digits == 0) { + result = scaled_string; + } else { + int64_t len = scaled_string.length; + if (len <= digits) { + // Add sufficient leading zeroes + Text_t z = Text$repeat(Text("0"), I(digits + 1 - len)); + scaled_string = Texts(z, scaled_string); + len = digits + 1; + } + Text_t whole = Text$slice(scaled_string, I(1), I(len - digits)); + Text_t fraction = Text$slice(scaled_string, I(len - digits + 1), I(-1)); + result = Texts(whole, ".", fraction); + } + if (Int$compare_value(scaled_int, I(0)) < 0) { + result = Texts("-", result); + } + return result; +} + +PUREFUNC +static int32_t Real$compare(const void *x, const void *y, const TypeInfo_t *info) { + (void)info; + Int_t x_int = Real$compute(*(Real_t *)x, 100); + Int_t y_int = Real$compute(*(Real_t *)y, 100); + return Int$compare_value(x_int, y_int); +} + +PUREFUNC +static bool Real$equal(const void *x, const void *y, const TypeInfo_t *info) { + (void)info; + Int_t x_int = Real$compute(*(Real_t *)x, 100); + Int_t y_int = Real$compute(*(Real_t *)y, 100); + return Int$equal_value(x_int, y_int); +} + +PUREFUNC +static uint64_t Real$hash(const void *x, const TypeInfo_t *info) { + (void)x, (void)info; + fail("Hashing is not implemented for Reals"); +} + +static Text_t Real$as_text(const void *x, bool color, const TypeInfo_t *info) { + (void)info; + if (x == NULL) return Text("Real"); + Text_t text = Real$value_as_text(*(Real_t *)x, 10); + return color ? Texts("\x1b[35m", text, "\x1b[m") : text; +} + +PUREFUNC +static bool Real$is_none(const void *x, const TypeInfo_t *info) { + (void)info; + return *(Real_t *)x == NULL; +} + +static void Real$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) { + (void)obj, (void)out, (void)pointers, (void)info; + fail("Serialization of Reals is not implemented"); +} + +static void Real$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *info) { + (void)in, (void)obj, (void)pointers, (void)info; + fail("Serialization of Reals is not implemented"); +} + +public +const TypeInfo_t Real$info = { + .size = sizeof(Real_t), + .align = __alignof__(Real_t), + .metamethods = + { + .compare = Real$compare, + .equal = Real$equal, + .hash = Real$hash, + .as_text = Real$as_text, + .is_none = Real$is_none, + .serialize = Real$serialize, + .deserialize = Real$deserialize, + }, +}; diff --git a/src/stdlib/reals.h b/src/stdlib/reals.h new file mode 100644 index 00000000..8750fdbb --- /dev/null +++ b/src/stdlib/reals.h @@ -0,0 +1,29 @@ +#include <gmp.h> +#include <stdint.h> + +#include "datatypes.h" +#include "types.h" + +#define NONE_REAL ((Real_t)NULL) + +Int_t Real$compute(Real_t r, int64_t decimals); +Text_t Real$value_as_text(Real_t x, int64_t decimals); + +OptionalReal_t Real$parse(Text_t text, Text_t *remainder); +Real_t Real$from_text(Text_t text); +Real_t Real$from_float64(double n); +Real_t Real$from_int(Int_t i); + +double Real$as_float64(Real_t x); +Int_t Real$as_int(Real_t x); + +Real_t Real$negative(Real_t x); +Real_t Real$sqrt(Real_t x); +Real_t Real$plus(Real_t x, Real_t y); +Real_t Real$minus(Real_t x, Real_t y); +Real_t Real$times(Real_t x, Real_t y); +Real_t Real$divided_by(Real_t x, Real_t y); +Real_t Real$left_shifted(Real_t x, Int_t amount); +Real_t Real$right_shifted(Real_t x, Int_t amount); + +extern const TypeInfo_t Real$info; diff --git a/src/stdlib/text.h b/src/stdlib/text.h index 856b173a..989fcb8b 100644 --- a/src/stdlib/text.h +++ b/src/stdlib/text.h @@ -7,9 +7,9 @@ #include <stdint.h> #include "datatypes.h" +#include "floats.h" // IWYU pragma: export #include "integers.h" // IWYU pragma: export #include "mapmacro.h" -#include "nums.h" // IWYU pragma: export #include "types.h" #include "util.h" @@ -46,8 +46,8 @@ static inline Text_t Text_from_text(Text_t t) { int16_t: Int16$value_as_text, \ int32_t: Int32$value_as_text, \ int64_t: Int64$value_as_text, \ - double: Num$value_as_text, \ - float: Num32$value_as_text, \ + double: Float64$value_as_text, \ + float: Float32$value_as_text, \ Int_t: Int$value_as_text)(x) Text_t Text$_concat(int n, Text_t items[n]); diff --git a/src/stdlib/tomo.h b/src/stdlib/tomo.h index ff8f90a2..6a9ba621 100644 --- a/src/stdlib/tomo.h +++ b/src/stdlib/tomo.h @@ -15,16 +15,17 @@ #include "datatypes.h" // IWYU pragma: export #include "enums.h" // IWYU pragma: export #include "files.h" // IWYU pragma: export +#include "floats.h" // IWYU pragma: export #include "functiontype.h" // IWYU pragma: export #include "integers.h" // IWYU pragma: export #include "lists.h" // IWYU pragma: export #include "memory.h" // IWYU pragma: export #include "metamethods.h" // IWYU pragma: export -#include "nums.h" // IWYU pragma: export #include "optionals.h" // IWYU pragma: export #include "paths.h" // IWYU pragma: export #include "pointers.h" // IWYU pragma: export #include "print.h" // IWYU pragma: export +#include "reals.h" // IWYU pragma: export #include "result.h" // IWYU pragma: export #include "siphash.h" // IWYU pragma: export #include "stacktrace.h" // IWYU pragma: export diff --git a/src/typecheck.c b/src/typecheck.c index a073cb2e..dc234bac 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -695,7 +695,7 @@ type_t *get_type(env_t *env, ast_t *ast) { return Type(BigIntType); } case Num: { - return Type(NumType, .bits = TYPE_NBITS64); + return Type(RealType); } case HeapAllocate: { type_t *pointed = get_type(env, Match(ast, HeapAllocate)->value); @@ -906,7 +906,7 @@ type_t *get_type(env_t *env, ast_t *ast) { binding_t *constructor = get_constructor(env, t, call->args, env->current_type != NULL && type_eq(env->current_type, t)); if (constructor) return t; - else if (t->tag == StructType || t->tag == IntType || t->tag == BigIntType || t->tag == NumType + else if (t->tag == StructType || t->tag == IntType || t->tag == BigIntType || t->tag == FloatType || t->tag == ByteType || t->tag == TextType || t->tag == CStringType) return t; // Constructor arg_t *arg_types = NULL; @@ -1075,7 +1075,7 @@ type_t *get_type(env_t *env, ast_t *ast) { case Negative: { ast_t *value = Match(ast, Negative)->value; type_t *t = get_type(env, value); - if (t->tag == IntType || t->tag == NumType) return t; + if (t->tag == IntType || t->tag == FloatType) return t; binding_t *b = get_namespace_binding(env, value, "negative"); if (b && b->type->tag == FunctionType) { @@ -1087,7 +1087,7 @@ type_t *get_type(env_t *env, ast_t *ast) { } case Not: { type_t *t = get_type(env, Match(ast, Not)->value); - if (t->tag == IntType || t->tag == NumType || t->tag == BoolType) return t; + if (t->tag == IntType || t->tag == FloatType || t->tag == BoolType) return t; if (t->tag == OptionalType) return Type(BoolType); ast_t *value = Match(ast, Not)->value; @@ -1132,8 +1132,8 @@ type_t *get_type(env_t *env, ast_t *ast) { non_opt = most_complete_type(non_opt, rhs_t); if (non_opt != NULL) return non_opt; } else if ((is_numeric_type(lhs_t) || lhs_t->tag == BoolType) - && (is_numeric_type(rhs_t) || rhs_t->tag == BoolType) && lhs_t->tag != NumType - && rhs_t->tag != NumType) { + && (is_numeric_type(rhs_t) || rhs_t->tag == BoolType) && lhs_t->tag != FloatType + && rhs_t->tag != FloatType) { if (can_compile_to_type(env, binop.rhs, lhs_t)) return lhs_t; else if (can_compile_to_type(env, binop.lhs, rhs_t)) return rhs_t; } else if (lhs_t->tag == TableType && rhs_t->tag == TableType && type_eq(lhs_t, rhs_t)) { @@ -1163,7 +1163,7 @@ type_t *get_type(env_t *env, ast_t *ast) { // Bitwise AND: if ((is_numeric_type(lhs_t) || lhs_t->tag == BoolType) && (is_numeric_type(rhs_t) || rhs_t->tag == BoolType) - && lhs_t->tag != NumType && rhs_t->tag != NumType) { + && lhs_t->tag != FloatType && rhs_t->tag != FloatType) { if (can_compile_to_type(env, binop.rhs, lhs_t)) return lhs_t; else if (can_compile_to_type(env, binop.lhs, rhs_t)) return rhs_t; } else if (lhs_t->tag == TableType && rhs_t->tag == TableType && type_eq(lhs_t, rhs_t)) { @@ -1193,7 +1193,7 @@ type_t *get_type(env_t *env, ast_t *ast) { // Bitwise XOR: if ((is_numeric_type(lhs_t) || lhs_t->tag == BoolType) && (is_numeric_type(rhs_t) || rhs_t->tag == BoolType) - && lhs_t->tag != NumType && rhs_t->tag != NumType) { + && lhs_t->tag != FloatType && rhs_t->tag != FloatType) { if (can_compile_to_type(env, binop.rhs, lhs_t)) return lhs_t; else if (can_compile_to_type(env, binop.lhs, rhs_t)) return rhs_t; } else if (lhs_t->tag == TableType && rhs_t->tag == TableType && type_eq(lhs_t, rhs_t)) { @@ -1699,7 +1699,7 @@ PUREFUNC bool can_compile_to_type(env_t *env, ast_t *ast, type_t *needed) { env = with_enum_scope(env, needed); if (is_numeric_type(needed) && ast->tag == Int) return true; - if (needed->tag == NumType && ast->tag == Num) return true; + if (needed->tag == FloatType && ast->tag == Num) return true; type_t *non_optional_needed = non_optional(needed); if (non_optional_needed->tag == ListType && ast->tag == List) { diff --git a/src/types.c b/src/types.c index 24453150..bffeb653 100644 --- a/src/types.c +++ b/src/types.c @@ -7,6 +7,7 @@ #include <sys/param.h> #include "environment.h" +#include "stdlib/datatypes.h" #include "stdlib/integers.h" #include "stdlib/tables.h" #include "stdlib/text.h" @@ -40,7 +41,8 @@ Text_t type_to_text(type_t *t) { case TextType: return Match(t, TextType)->lang ? Text$from_str(Match(t, TextType)->lang) : Text("Text"); case BigIntType: return Text("Int"); case IntType: return Texts("Int", (int32_t)Match(t, IntType)->bits); - case NumType: return Match(t, NumType)->bits == TYPE_NBITS32 ? Text("Num32") : Text("Num"); + case FloatType: return Match(t, FloatType)->bits == TYPE_NBITS32 ? Text("Float32") : Text("Float64"); + case RealType: return Text("Real"); case ListType: { DeclareMatch(list, t, ListType); return Texts("[", type_to_text(list->item_type), "]"); @@ -172,7 +174,7 @@ type_t *type_or_type(type_t *a, type_t *b) { if (type_is_a(a, b)) return b; if (a->tag == AbortType || a->tag == ReturnType) return non_optional(b); if (b->tag == AbortType || b->tag == ReturnType) return non_optional(a); - if ((a->tag == IntType || a->tag == NumType) && (b->tag == IntType || b->tag == NumType)) { + if (is_numeric_type(a) && is_numeric_type(b)) { switch (compare_precision(a, b)) { case NUM_PRECISION_EQUAL: case NUM_PRECISION_MORE: return a; @@ -198,7 +200,8 @@ static PUREFUNC INLINE double type_min_magnitude(type_t *t) { default: errx(1, "Invalid integer bit size"); } } - case NumType: return -1. / 0.; + case FloatType: return -1. / 0.; + case RealType: return -1. / 0.; default: return (double)NAN; } } @@ -217,7 +220,8 @@ static PUREFUNC INLINE double type_max_magnitude(type_t *t) { default: errx(1, "Invalid integer bit size"); } } - case NumType: return 1. / 0.; + case FloatType: return 1. / 0.; + case RealType: return 1. / 0.; default: return (double)NAN; } } @@ -225,15 +229,17 @@ static PUREFUNC INLINE double type_max_magnitude(type_t *t) { PUREFUNC precision_cmp_e compare_precision(type_t *a, type_t *b) { if (a == NULL || b == NULL) return NUM_PRECISION_INCOMPARABLE; - if (is_int_type(a) && b->tag == NumType) return NUM_PRECISION_LESS; - else if (a->tag == NumType && is_int_type(b)) return NUM_PRECISION_MORE; - double a_min = type_min_magnitude(a), b_min = type_min_magnitude(b), a_max = type_max_magnitude(a), b_max = type_max_magnitude(b); if (isnan(a_min) || isnan(b_min) || isnan(a_max) || isnan(b_max)) return NUM_PRECISION_INCOMPARABLE; - else if (a_min == b_min && a_max == b_max) return NUM_PRECISION_EQUAL; - else if (a_min <= b_min && b_max <= a_max) return NUM_PRECISION_MORE; + else if (a_min == b_min && a_max == b_max) { + if (is_int_type(a) && (b->tag == FloatType || b->tag == RealType)) return NUM_PRECISION_LESS; + else if ((a->tag == FloatType || a->tag == RealType) && is_int_type(b)) return NUM_PRECISION_MORE; + else if (a->tag == FloatType && b->tag == RealType) return NUM_PRECISION_LESS; + else if (a->tag == RealType && b->tag == FloatType) return NUM_PRECISION_MORE; + return NUM_PRECISION_EQUAL; + } else if (a_min <= b_min && b_max <= a_max) return NUM_PRECISION_MORE; else if (b_min <= a_min && a_max <= b_max) return NUM_PRECISION_LESS; else return NUM_PRECISION_INCOMPARABLE; } @@ -250,6 +256,7 @@ bool _has_heap_memory(type_t *t, Table_t *visited) { case PointerType: return true; case OptionalType: return _has_heap_memory(Match(t, OptionalType)->type, visited); case BigIntType: return true; + case RealType: return true; case StructType: { for (arg_t *field = Match(t, StructType)->fields; field; field = field->next) { if (_has_heap_memory(field->type, visited)) return true; @@ -362,11 +369,13 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) { // Serialization/deserialization if (type_eq(actual, Type(ListType, Type(ByteType))) || type_eq(needed, Type(ListType, Type(ByteType)))) return true; - if (actual->tag == NumType && needed->tag == IntType) return false; + if (is_numeric_type(actual) && needed->tag == RealType) return true; + + if (actual->tag == FloatType && needed->tag == IntType) return false; - if (actual->tag == IntType && (needed->tag == NumType || needed->tag == BigIntType)) return true; + if (actual->tag == IntType && (needed->tag == FloatType || needed->tag == BigIntType)) return true; - if (actual->tag == BigIntType && needed->tag == NumType) return true; + if (actual->tag == BigIntType && needed->tag == FloatType) return true; if (actual->tag == IntType && needed->tag == IntType) { precision_cmp_e cmp = compare_precision(actual, needed); @@ -388,7 +397,8 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) { if (Match(actual, OptionalType)->type == NULL) return (needed->tag == OptionalType); // Optional num -> num - if (needed->tag == NumType && actual->tag == OptionalType && Match(actual, OptionalType)->type->tag == NumType) + if (needed->tag == FloatType && actual->tag == OptionalType + && Match(actual, OptionalType)->type->tag == FloatType) return can_promote(Match(actual, OptionalType)->type, needed); } @@ -464,11 +474,11 @@ PUREFUNC bool is_int_type(type_t *t) { } PUREFUNC bool is_numeric_type(type_t *t) { - return t->tag == IntType || t->tag == BigIntType || t->tag == NumType || t->tag == ByteType; + return t->tag == IntType || t->tag == BigIntType || t->tag == FloatType || t->tag == ByteType || t->tag == RealType; } PUREFUNC bool is_packed_data(type_t *t) { - if (t->tag == IntType || t->tag == NumType || t->tag == ByteType || t->tag == PointerType || t->tag == BoolType + if (t->tag == IntType || t->tag == FloatType || t->tag == ByteType || t->tag == PointerType || t->tag == BoolType || t->tag == FunctionType) { return true; } else if (t->tag == StructType) { @@ -552,7 +562,8 @@ PUREFUNC size_t type_size(type_t *t) { default: errx(1, "Invalid integer bit size"); } } - case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? sizeof(double) : sizeof(float); + case FloatType: return Match(t, FloatType)->bits == TYPE_NBITS64 ? sizeof(double) : sizeof(float); + case RealType: return sizeof(Real_t); case TextType: return sizeof(Text_t); case ListType: return sizeof(List_t); case TableType: return sizeof(Table_t); @@ -640,7 +651,8 @@ PUREFUNC size_t type_align(type_t *t) { default: return 0; } } - case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? __alignof__(double) : __alignof__(float); + case FloatType: return Match(t, FloatType)->bits == TYPE_NBITS64 ? __alignof__(double) : __alignof__(float); + case RealType: return __alignof__(Real_t); case TextType: return __alignof__(Text_t); case ListType: return __alignof__(List_t); case TableType: return __alignof__(Table_t); diff --git a/src/types.h b/src/types.h index df5729ca..f6b2f43f 100644 --- a/src/types.h +++ b/src/types.h @@ -47,7 +47,8 @@ struct type_s { ByteType, BigIntType, IntType, - NumType, + RealType, + FloatType, CStringType, TextType, ListType, @@ -76,8 +77,10 @@ struct type_s { struct { } ByteType; struct { + } RealType; + struct { enum { TYPE_NBITS32 = 32, TYPE_NBITS64 = 64 } bits; - } NumType; + } FloatType; struct { } CStringType; struct { @@ -131,7 +134,8 @@ struct type_s { #define Type(typetag, ...) new (type_t, .tag = typetag, .__data.typetag = {__VA_ARGS__}) #define INT_TYPE Type(BigIntType) -#define NUM_TYPE Type(NumType, .bits = TYPE_NBITS64) +#define REAL_TYPE Type(RealType) +#define NUM_TYPE Type(FloatType, .bits = TYPE_NBITS64) #define NewFunctionType(ret, ...) \ _make_function_type(ret, sizeof((arg_t[]){__VA_ARGS__}) / sizeof(arg_t), (arg_t[]){__VA_ARGS__}) diff --git a/test/_vectors.tm b/test/_vectors.tm index 84646cc9..85c25ca0 100644 --- a/test/_vectors.tm +++ b/test/_vectors.tm @@ -1 +1 @@ -struct Vec2(x,y:Num) +struct Vec2(x,y:Float64) diff --git a/test/lists.tm b/test/lists.tm index 4e9f769b..832c18ba 100644 --- a/test/lists.tm +++ b/test/lists.tm @@ -1,10 +1,10 @@ func main() do - nums : [Num32] = [] + nums : [Float32] = [] assert nums == [] do - nums : [Num32] + nums : [Float32] assert nums == [] do diff --git a/test/minmax.tm b/test/minmax.tm index 038f03e4..3c6d7efd 100644 --- a/test/minmax.tm +++ b/test/minmax.tm @@ -1,7 +1,7 @@ struct Foo(x:Int, y:Int) - func len(f:Foo->Num) - return Num.sqrt(Num(f.x*f.x + f.y*f.y))! + func len(f:Foo->Float64) + return Float64.sqrt(Float64(f.x*f.x + f.y*f.y))! func main() assert (3 _min_ 5) == 3 diff --git a/test/nums.tm b/test/nums.tm index ef139d0d..9077a67f 100644 --- a/test/nums.tm +++ b/test/nums.tm @@ -8,14 +8,14 @@ func main() assert n - n == 0. - assert Num.PI == 3.141592653589793 + assert Float64.PI == 3.141592653589793 - assert Num.PI.with_precision(0.01) == 3.14 + assert Float64.PI.with_precision(0.01) == 3.14 - assert Num.INF == Num.INF - assert Num.INF.isinf() + assert Float64.INF == Float64.INF + assert Float64.INF.isinf() - none_num : Num? = none + none_num : Float64? = none assert none_num == none assert none_num == none_num assert (none_num < none_num) == no @@ -36,17 +36,17 @@ func main() # >> 0./0. # = none - assert Num.PI.cos()!.near(-1) - assert Num.PI.sin()!.near(0) + assert Float64.PI.cos()!.near(-1) + assert Float64.PI.sin()!.near(0) - assert Num.INF.near(-Num.INF) == no + assert Float64.INF.near(-Float64.INF) == no - assert Num32.sqrt(16) == Num32(4) - assert Num32.sqrt(-1) == none + assert Float32.sqrt(16) == Float32(4) + assert Float32.sqrt(-1) == none assert (0.25).mix(10, 20) == 12.5 assert (2.0).mix(10, 20) == 30. - assert Num(5) == 5. + assert Float64(5) == 5. assert (0.5).percent() == "50%" diff --git a/test/optionals.tm b/test/optionals.tm index d26a9d46..53741748 100644 --- a/test/optionals.tm +++ b/test/optionals.tm @@ -43,7 +43,7 @@ func maybe_text(should_i:Bool->Text?) else return none -func maybe_num(should_i:Bool->Num?) +func maybe_num(should_i:Bool->Float64?) if should_i return 12.3 else diff --git a/test/serialization.tm b/test/serialization.tm index 39c1624f..619ddb1e 100644 --- a/test/serialization.tm +++ b/test/serialization.tm @@ -1,7 +1,7 @@ struct Foo(name:Text, next:@Foo?=none) -enum MyEnum(Zero, One(x:Int), Two(x:Num, y:Text)) +enum MyEnum(Zero, One(x:Int), Two(x:Float64, y:Text)) func main() do @@ -74,9 +74,9 @@ func main() assert roundtrip == obj do - >> obj : Num? = none + >> obj : Float64? = none >> bytes : [Byte] = obj - >> roundtrip : Num? = bytes + >> roundtrip : Float64? = bytes assert roundtrip == obj do |
