-
Notifications
You must be signed in to change notification settings - Fork 375
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stdlibs): add
math/overflow
(#1698)
## Description This PR ports over the overflow stdlib to Gno. The addition of this library will enable adding Coin functionality already existing in tm2's [coin.go](https://github.com/gnolang/gno/blob/master/tm2/pkg/std/coin.go) the [Coin/Coins](https://github.com/gnolang/gno/blob/master/gnovm/stdlibs/std/coins.gno) in Gno. The tests pass fully, and the library was simply copy-pasted. As per the conversation below, this PR also deprecates/removes the `examples/` package for `overflow`, as it makes more sense to have `overflow` be a part of stdlibs. This will unblock #1696. cc @thehowl <details><summary>Contributors' checklist...</summary> - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [x] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md). </details> --------- Co-authored-by: Hariom Verma <hariom18599@gmail.com>
- Loading branch information
Showing
11 changed files
with
228 additions
and
210 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
module gno.land/p/demo/groups | ||
|
||
require ( | ||
gno.land/p/demo/maths v0.0.0-latest | ||
gno.land/p/demo/rat v0.0.0-latest | ||
gno.land/r/demo/boards v0.0.0-latest | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module gno.land/p/demo/rat |
2 changes: 1 addition & 1 deletion
2
examples/gno.land/p/demo/maths/maths.gno → examples/gno.land/p/demo/rat/maths.gno
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package maths | ||
package rat | ||
|
||
const ( | ||
intSize = 32 << (^uint(0) >> 63) // 32 or 64 | ||
|
2 changes: 1 addition & 1 deletion
2
examples/gno.land/p/demo/maths/rat.gno → examples/gno.land/p/demo/rat/rat.gno
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package maths | ||
package rat | ||
|
||
//---------------------------------------- | ||
// Rat fractions | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
package overflow | ||
|
||
import ( | ||
"math" | ||
"testing" | ||
) | ||
|
||
// sample all possibilities of 8 bit numbers | ||
// by checking against 64 bit numbers | ||
|
||
func TestAlgorithms(t *testing.T) { | ||
errors := 0 | ||
|
||
for a64 := int64(math.MinInt8); a64 <= int64(math.MaxInt8); a64++ { | ||
for b64 := int64(math.MinInt8); b64 <= int64(math.MaxInt8) && errors < 10; b64++ { | ||
|
||
a8 := int8(a64) | ||
b8 := int8(b64) | ||
|
||
if int64(a8) != a64 || int64(b8) != b64 { | ||
t.Fatal("LOGIC FAILURE IN TEST") | ||
} | ||
|
||
// ADDITION | ||
{ | ||
r64 := a64 + b64 | ||
|
||
// now the verification | ||
result, ok := Add8(a8, b8) | ||
if ok && int64(result) != r64 { | ||
t.Errorf("failed to fail on %v + %v = %v instead of %v\n", | ||
a8, b8, result, r64) | ||
errors++ | ||
} | ||
if !ok && int64(result) == r64 { | ||
t.Fail() | ||
errors++ | ||
} | ||
} | ||
|
||
// SUBTRACTION | ||
{ | ||
r64 := a64 - b64 | ||
|
||
// now the verification | ||
result, ok := Sub8(a8, b8) | ||
if ok && int64(result) != r64 { | ||
t.Errorf("failed to fail on %v - %v = %v instead of %v\n", | ||
a8, b8, result, r64) | ||
} | ||
if !ok && int64(result) == r64 { | ||
t.Fail() | ||
errors++ | ||
} | ||
} | ||
|
||
// MULTIPLICATION | ||
{ | ||
r64 := a64 * b64 | ||
|
||
// now the verification | ||
result, ok := Mul8(a8, b8) | ||
if ok && int64(result) != r64 { | ||
t.Errorf("failed to fail on %v * %v = %v instead of %v\n", | ||
a8, b8, result, r64) | ||
errors++ | ||
} | ||
if !ok && int64(result) == r64 { | ||
t.Fail() | ||
errors++ | ||
} | ||
} | ||
|
||
// DIVISION | ||
if b8 != 0 { | ||
r64 := a64 / b64 | ||
rem64 := a64 % b64 | ||
|
||
// now the verification | ||
result, rem, ok := Quo8(a8, b8) | ||
if ok && int64(result) != r64 { | ||
t.Errorf("failed to fail on %v / %v = %v instead of %v\n", | ||
a8, b8, result, r64) | ||
errors++ | ||
} | ||
if ok && int64(rem) != rem64 { | ||
t.Errorf("failed to fail on %v %% %v = %v instead of %v\n", | ||
a8, b8, rem, rem64) | ||
errors++ | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
func TestQuotient(t *testing.T) { | ||
q, r, ok := Quo(100, 3) | ||
if r != 1 || q != 33 || !ok { | ||
t.Errorf("expected 100/3 => 33, r=1") | ||
} | ||
if _, _, ok = Quo(1, 0); ok { | ||
t.Error("unexpected lack of failure") | ||
} | ||
} | ||
|
||
func TestLong(t *testing.T) { | ||
if testing.Short() { | ||
t.Skip() | ||
} | ||
|
||
ctr := int64(0) | ||
|
||
for a64 := int64(math.MinInt16); a64 <= int64(math.MaxInt16); a64++ { | ||
for b64 := int64(math.MinInt16); b64 <= int64(math.MaxInt16); b64++ { | ||
a16 := int16(a64) | ||
b16 := int16(b64) | ||
if int64(a16) != a64 || int64(b16) != b64 { | ||
panic("LOGIC FAILURE IN TEST") | ||
} | ||
ctr++ | ||
|
||
// ADDITION | ||
{ | ||
r64 := a64 + b64 | ||
|
||
// now the verification | ||
result, ok := Add16(a16, b16) | ||
if int64(math.MinInt16) <= r64 && r64 <= int64(math.MaxInt16) { | ||
if !ok || int64(result) != r64 { | ||
println("add", a16, b16, result, r64) | ||
panic("incorrect result for non-overflow") | ||
} | ||
} else { | ||
if ok { | ||
println("add", a16, b16, result, r64) | ||
panic("incorrect ok result") | ||
} | ||
} | ||
} | ||
|
||
// SUBTRACTION | ||
{ | ||
r64 := a64 - b64 | ||
|
||
// now the verification | ||
result, ok := Sub16(a16, b16) | ||
if int64(math.MinInt16) <= r64 && r64 <= int64(math.MaxInt16) { | ||
if !ok || int64(result) != r64 { | ||
println("sub", a16, b16, result, r64) | ||
panic("incorrect result for non-overflow") | ||
} | ||
} else { | ||
if ok { | ||
println("sub", a16, b16, result, r64) | ||
panic("incorrect ok result") | ||
} | ||
} | ||
} | ||
|
||
// MULTIPLICATION | ||
{ | ||
r64 := a64 * b64 | ||
|
||
// now the verification | ||
result, ok := Mul16(a16, b16) | ||
if int64(math.MinInt16) <= r64 && r64 <= int64(math.MaxInt16) { | ||
if !ok || int64(result) != r64 { | ||
println("mul", a16, b16, result, r64) | ||
panic("incorrect result for non-overflow") | ||
} | ||
} else { | ||
if ok { | ||
println("mul", a16, b16, result, r64) | ||
panic("incorrect ok result") | ||
} | ||
} | ||
} | ||
|
||
// DIVISION | ||
if b16 != 0 { | ||
r64 := a64 / b64 | ||
|
||
// now the verification | ||
result, _, ok := Quo16(a16, b16) | ||
if int64(math.MinInt16) <= r64 && r64 <= int64(math.MaxInt16) { | ||
if !ok || int64(result) != r64 { | ||
println("quo", a16, b16, result, r64) | ||
panic("incorrect result for non-overflow") | ||
} | ||
} else { | ||
if ok { | ||
println("quo", a16, b16, result, r64) | ||
panic("incorrect ok result") | ||
} | ||
} | ||
} | ||
} | ||
} | ||
println("done", ctr) | ||
} |
Oops, something went wrong.