Skip to content

Commit

Permalink
feat(stdlib): Add ** to Float64 and Float32 (#2163)
Browse files Browse the repository at this point in the history
  • Loading branch information
spotandjake authored Sep 21, 2024
1 parent 6755782 commit 7542d92
Show file tree
Hide file tree
Showing 8 changed files with 594 additions and 346 deletions.
68 changes: 68 additions & 0 deletions compiler/test/stdlib/float32.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,74 @@ assert fromNumber(0) == 0.0f
assert toNumber(555.0f) == 555
assert toNumber(0.0f) == 0

// Float32.pow tests are based on test cases from libc-test: http://nsz.repo.hu/git/?p=libc-test
/*
libc-test is licensed under the following standard MIT license:
Copyright © 2005-2013 libc-test AUTHORS
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Portions of this software is derived from software authored by
third parties:
math tests use numbers under BSD and GPL licenses see src/math/ucb/*
and src/math/crlibm/* for details
*/
// pow
assert Float32.isNaN(-8.06684839057968084f ** 4.53566256067686879f)
assert 4.34523984933830487f ** -8.88799136300345083f == 0.000002134714122803416f
assert Float32.isNaN(-8.38143342755524934f ** -2.76360733737958819f)
assert Float32.isNaN(-6.53167358191348413f ** 4.56753527684274374f)
assert 9.26705696697258574f ** 4.81139208435979615f == 44909.33203125f
assert Float32.isNaN(-6.45004555606023633f ** 0.662071792337673881f)
assert 7.85889025304169664f ** 0.0521545267500622481f == 1.11351774134586523f
assert Float32.isNaN(-0.792054511984895959f ** 7.67640268511753998f)
assert 0.615702673197924044f ** 2.01190257903248026f == 0.37690776586532595f
assert Float32.isNaN(-0.558758682360915193f ** 0.0322398306026380407f)
assert Float32.isNaN(0.0f ** NaNf)
assert 0.0f ** Infinityf == 0.0f
assert 0.0f ** 3.0f == 0.0f
assert 0.0f ** 2.0f == 0.0f
assert 0.0f ** 1.0f == 0.0f
assert 0.0f ** 0.5f == 0.0f
assert Float32.isNaN(0.0f ** 0.0f)
assert Float32.isNaN(0.0f ** -0.0f)
assert 0.0f ** -0.5f == Infinityf
assert 0.0f ** -1.0f == Infinityf
assert 0.0f ** -Infinityf == Infinityf
assert Float32.isNaN(-0.0f ** NaNf)
assert -0.0f ** Infinityf == 0.0f
assert -0.0f ** 3.0f == -0.0f
assert -0.0f ** 0.5f == 0.0f
assert Float32.isNaN(-0.0f ** 0.0f)
assert Float32.isNaN(-0.0f ** -0.0f)
assert -0.0f ** -0.5f == Infinityf
assert -0.0f ** -1.0f == -Infinityf
assert -0.0f ** -2.0f == Infinityf
assert -0.0f ** -3.0f == -Infinityf
assert -0.0f ** -4.0f == Infinityf
assert -0.0f ** -Infinityf == Infinityf
assert Float32.isNaN(NaNf ** 0.0f)
assert Float32.isNaN(Infinityf ** 0.0f)
assert Float32.isNaN(-Infinityf ** 0.0f)
assert Float32.isNaN(1.0f ** 0.0f)
assert Float32.isNaN(-1.0f ** 0.0f)
assert Float32.isNaN(-0.5f ** 0.0f)
assert Float32.isNaN(NaNf ** -0.0f)
assert 300.0f ** 1.0f == 300.0f

assert 5.0f > 4.0f
assert 5.0f >= 5.0f
assert 5.0f < 17.0f
Expand Down
69 changes: 69 additions & 0 deletions compiler/test/stdlib/float64.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,75 @@ assert fromNumber(-1.7976931348623157e+309) == -Infinityd
assert toNumber(555.0d) == 555
assert toNumber(0.0d) == 0

// Float64.pow tests are based on test cases from libc-test: http://nsz.repo.hu/git/?p=libc-test
/*
libc-test is licensed under the following standard MIT license:
Copyright © 2005-2013 libc-test AUTHORS
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Portions of this software is derived from software authored by
third parties:
math tests use numbers under BSD and GPL licenses see src/math/ucb/*
and src/math/crlibm/* for details
*/
// pow
assert Float64.isNaN(-8.06684839057968084d ** 4.53566256067686879d)
assert 4.34523984933830487d ** -8.88799136300345083d ==
0.00000213471188255872853d
assert Float64.isNaN(-8.38143342755524934d ** -2.76360733737958819d)
assert Float64.isNaN(-6.53167358191348413d ** 4.56753527684274374d)
assert 9.26705696697258574d ** 4.81139208435979615d == 44909.2994151296589d
assert Float64.isNaN(-6.45004555606023633d ** 0.662071792337673881d)
assert 7.85889025304169664d ** 0.0521545267500622481d == 1.11351774134586523d
assert Float64.isNaN(-0.792054511984895959d ** 7.67640268511753998d)
assert 0.615702673197924044d ** 2.01190257903248026d == 0.376907735213801831d
assert Float64.isNaN(-0.558758682360915193d ** 0.0322398306026380407d)
assert Float64.isNaN(0.0d ** NaNd)
assert 0.0d ** Infinityd == 0.0d
assert 0.0d ** 3.0d == 0.0d
assert 0.0d ** 2.0d == 0.0d
assert 0.0d ** 1.0d == 0.0d
assert 0.0d ** 0.5d == 0.0d
assert Float64.isNaN(0.0d ** 0.0d)
assert Float64.isNaN(0.0d ** -0.0d)
assert 0.0d ** -0.5d == Infinityd
assert 0.0d ** -1.0d == Infinityd
assert 0.0d ** -Infinityd == Infinityd
assert Float64.isNaN(-0.0d ** NaNd)
assert -0.0d ** Infinityd == 0.0d
assert -0.0d ** 3.0d == -0.0d
assert -0.0d ** 0.5d == 0.0d
assert Float64.isNaN(-0.0d ** 0.0d)
assert Float64.isNaN(-0.0d ** -0.0d)
assert -0.0d ** -0.5d == Infinityd
assert -0.0d ** -1.0d == -Infinityd
assert -0.0d ** -2.0d == Infinityd
assert -0.0d ** -3.0d == -Infinityd
assert -0.0d ** -4.0d == Infinityd
assert -0.0d ** -Infinityd == Infinityd
assert Float64.isNaN(NaNd ** 0.0d)
assert Float64.isNaN(Infinityd ** 0.0d)
assert Float64.isNaN(-Infinityd ** 0.0d)
assert Float64.isNaN(1.0d ** 0.0d)
assert Float64.isNaN(-1.0d ** 0.0d)
assert Float64.isNaN(-0.5d ** 0.0d)
assert Float64.isNaN(NaNd ** -0.0d)
assert 300.0d ** 1.0d == 300.0d

assert 5.0d > 4.0d
assert 5.0d >= 5.0d
assert 5.0d < 17.0d
Expand Down
26 changes: 26 additions & 0 deletions stdlib/float32.gr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Float32

from "runtime/unsafe/wasmi32" include WasmI32
from "runtime/unsafe/wasmf32" include WasmF32
from "runtime/unsafe/wasmf64" include WasmF64
use WasmF32.{ (+), (-), (*), (/), (<), (<=), (>), (>=) }
from "runtime/dataStructures" include DataStructures
use DataStructures.{ newFloat32 }
Expand Down Expand Up @@ -156,6 +157,31 @@ provide let (/) = (x: Float32, y: Float32) => {
WasmI32.toGrain(ptr): Float32
}

/**
* Computes the exponentiation of the given base and power.
*
* @param base: The base float
* @param power: The exponent float
* @returns The base raised to the given power
*
* @example
* use Float64.{ (**) }
* assert 2.0f ** 2.0f == 4.0f
*
* @since v0.7.0
*/
@unsafe
provide let (**) = (base: Float32, power: Float32) => {
let basev = WasmF32.load(WasmI32.fromGrain(base), _VALUE_OFFSET)
let powerv = WasmF32.load(WasmI32.fromGrain(power), _VALUE_OFFSET)
let value = Numbers.powf(
WasmF64.promoteF32(basev),
WasmF64.promoteF32(powerv)
)
let ptr = newFloat32(WasmF32.demoteF64(value))
WasmI32.toGrain(ptr): Float32
}

/**
* Checks if the first value is less than the second value.
*
Expand Down
33 changes: 33 additions & 0 deletions stdlib/float32.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,39 @@ use Float32.{ (/) }
assert 10.0f / 4.0f == 2.5f
```

### Float32.**(\*\*)**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
(**) : (base: Float32, power: Float32) => Float32
```

Computes the exponentiation of the given base and power.

Parameters:

|param|type|description|
|-----|----|-----------|
|`base`|`Float32`|The base float|
|`power`|`Float32`|The exponent float|

Returns:

|type|description|
|----|-----------|
|`Float32`|The base raised to the given power|

Examples:

```grain
use Float64.{ (**) }
assert 2.0f ** 2.0f == 4.0f
```

### Float32.**(<)**

<details>
Expand Down
21 changes: 21 additions & 0 deletions stdlib/float64.gr
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,27 @@ provide let (/) = (x: Float64, y: Float64) => {
WasmI32.toGrain(ptr): Float64
}

/**
* Computes the exponentiation of the given base and power.
*
* @param base: The base float
* @param power: The exponent float
* @returns The base raised to the given power
*
* @example
* use Float64.{ (**) }
* assert 2.0d ** 2.0d == 4.0d
*
* @since v0.7.0
*/
@unsafe
provide let (**) = (base: Float64, power: Float64) => {
let basev = WasmF64.load(WasmI32.fromGrain(base), _VALUE_OFFSET)
let powerv = WasmF64.load(WasmI32.fromGrain(power), _VALUE_OFFSET)
let ptr = newFloat64(Numbers.powf(basev, powerv))
WasmI32.toGrain(ptr): Float64
}

/**
* Checks if the first value is less than the second value.
*
Expand Down
33 changes: 33 additions & 0 deletions stdlib/float64.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,39 @@ use Float64.{ (/) }
assert 25.0d / 4.0d == 6.25d
```

### Float64.**(\*\*)**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
(**) : (base: Float64, power: Float64) => Float64
```

Computes the exponentiation of the given base and power.

Parameters:

|param|type|description|
|-----|----|-----------|
|`base`|`Float64`|The base float|
|`power`|`Float64`|The exponent float|

Returns:

|type|description|
|----|-----------|
|`Float64`|The base raised to the given power|

Examples:

```grain
use Float64.{ (**) }
assert 2.0d ** 2.0d == 4.0d
```

### Float64.**(<)**

<details>
Expand Down
Loading

0 comments on commit 7542d92

Please sign in to comment.