From fb1d481715974c6639588a9a72d4739516319e40 Mon Sep 17 00:00:00 2001 From: Spotandjake <40705786+spotandjake@users.noreply.github.com> Date: Sun, 28 Jul 2024 17:12:53 -0400 Subject: [PATCH] feat(stdlib): Add `abs`, `neg`, `isNaN`, `isInfinite` to `Float32` (#2116) Co-authored-by: Oscar Spencer --- compiler/test/stdlib/float32.test.gr | 32 ++++++ stdlib/float32.gr | 68 +++++++++++ stdlib/float32.md | 164 +++++++++++++++++++++++++++ 3 files changed, 264 insertions(+) diff --git a/compiler/test/stdlib/float32.test.gr b/compiler/test/stdlib/float32.test.gr index 87742c5d4..4d4987524 100644 --- a/compiler/test/stdlib/float32.test.gr +++ b/compiler/test/stdlib/float32.test.gr @@ -41,3 +41,35 @@ assert compare(1.0f, 1.0f) == 0 assert compare(nan, nan) == 0 assert compare(1.0f, nan) > 0 assert compare(nan, 1.0f) < 0 + +// isNaN +assert Float32.isNaN(NaNf) +assert Float32.isNaN(1.0f) == false +assert Float32.isNaN(0.0f) == false +assert Float32.isNaN(-1.0f) == false +assert Float32.isNaN(25.76f) == false +assert Float32.isNaN(-25.00f) == false +assert Float32.isNaN(Infinityf) == false +assert Float32.isNaN(-Infinityf) == false + +// isInfinite +assert Float32.isInfinite(Infinityf) +assert Float32.isInfinite(-Infinityf) +assert Float32.isInfinite(NaNf) == false +assert Float32.isInfinite(1.0f) == false +assert Float32.isInfinite(0.0f) == false +assert Float32.isInfinite(-1.0f) == false +assert Float32.isInfinite(25.76f) == false +assert Float32.isInfinite(-25.00f) == false + +// abs +assert Float32.abs(-25.5f) == 25.5f +assert Float32.abs(25.5f) == 25.5f +assert Float32.isNaN(Float32.abs(NaNf)) +assert Float32.abs(Infinityf) == Infinityf + +// neg +assert Float32.neg(-25.5f) == 25.5f +assert Float32.neg(25.5f) == -25.5f +assert Float32.isNaN(-NaNf) +assert Float32.neg(Infinityf) == -Infinityf diff --git a/stdlib/float32.gr b/stdlib/float32.gr index 6e0613360..3830a88e4 100644 --- a/stdlib/float32.gr +++ b/stdlib/float32.gr @@ -247,3 +247,71 @@ provide let (>=) = (x: Float32, y: Float32) => { let yv = WasmF32.load(WasmI32.fromGrain(y), _VALUE_OFFSET) xv >= yv } + +/** + * Checks if the value is a float NaN value (Not A Number). + * + * @param x: The value to check + * @returns `true` if the value is NaN, otherwise `false` + * + * @example Float32.isNaN(NaNf) + * @example Float32.isNaN(Infinityf) == false + * @example Float32.isNaN(-Infinityf) == false + * @example Float32.isNaN(0.5f) == false + * @example Float32.isNaN(1.0f) == false + * + * @since v0.6.5 + */ +provide let isNaN = (x: Float32) => x != x + +/** + * Checks if a float is infinite, that is either of positive or negative infinity. + * + * @param x: The value to check + * @returns `true` if the value is infinite or `false` otherwise + * + * @example Float32.isInfinite(Infinityf) + * @example Float32.isInfinite(-Infinityf) + * @example Float32.isInfinite(NaNf) == false + * @example Float32.isInfinite(0.5f) == false + * @example Float32.isInfinite(1.0f) == false + * + * @since v0.6.5 + */ +provide let isInfinite = (x: Float32) => x == Infinityf || x == -Infinityf + +/** + * Returns the absolute value. That is, it returns `x` if `x` is positive or zero and the negation of `x` if `x` is negative. + * + * @param x: The operand + * @returns The absolute value of the operand + * + * @example Float32.abs(-1.0f) == 1.0f + * @example Float32.abs(5.0f) == 5.0f + * + * @since v0.6.5 + */ +@unsafe +provide let abs = (x: Float32) => { + let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET) + let ptr = newFloat32(WasmF32.abs(xv)) + WasmI32.toGrain(ptr): Float32 +} + +/** + * Returns the negation of its operand. + * + * @param x: The operand + * @returns The negated operand + * + * @example Float32.neg(-1.0f) == 1.0f + * @example Float32.neg(1.0f) == -1.0f + * + * @since v0.6.5 + */ +@unsafe +provide let neg = (x: Float32) => { + let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET) + let ptr = newFloat32(WasmF32.neg(xv)) + WasmI32.toGrain(ptr): Float32 +} diff --git a/stdlib/float32.md b/stdlib/float32.md index 04e486a69..ae06f0f6d 100644 --- a/stdlib/float32.md +++ b/stdlib/float32.md @@ -480,3 +480,167 @@ use Float32.{ (>=) } assert 3.0f >= 3.0f ``` +### Float32.**isNaN** + +
+Added in next +No other changes yet. +
+ +```grain +isNaN : (x: Float32) => Bool +``` + +Checks if the value is a float NaN value (Not A Number). + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`x`|`Float32`|The value to check| + +Returns: + +|type|description| +|----|-----------| +|`Bool`|`true` if the value is NaN, otherwise `false`| + +Examples: + +```grain +Float32.isNaN(NaNf) +``` + +```grain +Float32.isNaN(Infinityf) == false +``` + +```grain +Float32.isNaN(-Infinityf) == false +``` + +```grain +Float32.isNaN(0.5f) == false +``` + +```grain +Float32.isNaN(1.0f) == false +``` + +### Float32.**isInfinite** + +
+Added in next +No other changes yet. +
+ +```grain +isInfinite : (x: Float32) => Bool +``` + +Checks if a float is infinite, that is either of positive or negative infinity. + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`x`|`Float32`|The value to check| + +Returns: + +|type|description| +|----|-----------| +|`Bool`|`true` if the value is infinite or `false` otherwise| + +Examples: + +```grain +Float32.isInfinite(Infinityf) +``` + +```grain +Float32.isInfinite(-Infinityf) +``` + +```grain +Float32.isInfinite(NaNf) == false +``` + +```grain +Float32.isInfinite(0.5f) == false +``` + +```grain +Float32.isInfinite(1.0f) == false +``` + +### Float32.**abs** + +
+Added in next +No other changes yet. +
+ +```grain +abs : (x: Float32) => Float32 +``` + +Returns the absolute value. That is, it returns `x` if `x` is positive or zero and the negation of `x` if `x` is negative. + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`x`|`Float32`|The operand| + +Returns: + +|type|description| +|----|-----------| +|`Float32`|The absolute value of the operand| + +Examples: + +```grain +Float32.abs(-1.0f) == 1.0f +``` + +```grain +Float32.abs(5.0f) == 5.0f +``` + +### Float32.**neg** + +
+Added in next +No other changes yet. +
+ +```grain +neg : (x: Float32) => Float32 +``` + +Returns the negation of its operand. + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`x`|`Float32`|The operand| + +Returns: + +|type|description| +|----|-----------| +|`Float32`|The negated operand| + +Examples: + +```grain +Float32.neg(-1.0f) == 1.0f +``` + +```grain +Float32.neg(1.0f) == -1.0f +``` +