Skip to content

Commit

Permalink
move the code from gnoswap repo to a go file.
Browse files Browse the repository at this point in the history
  • Loading branch information
notJoon committed Mar 11, 2024
1 parent 324ffd4 commit c4128cb
Show file tree
Hide file tree
Showing 13 changed files with 2,419 additions and 111 deletions.
601 changes: 601 additions & 0 deletions bits.go

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions bits_errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !compiler_bootstrap

package u256

import (
"errors"
)

//go:linkname overflowError runtime.overflowError
var overflowError error = errors.New("u256: integer overflow")

//go:linkname divideError runtime.divideError
var divideError error = errors.New("u256: integer divide by zero")
79 changes: 79 additions & 0 deletions bits_table.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
module github.com/gnoswap-labs/int256
module github.com/gnoswap-labs/uint256

go 1.21.6

require github.com/holiman/uint256 v1.2.4 // indirect
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
253 changes: 253 additions & 0 deletions i256.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
package u256

// signed integer wrapper

type Int struct {
v Uint
}

func NewInt(v int64) *Int {
if v >= 0 {
return &Int{v: *NewUint(uint64(v))}
}
return &Int{
v: Uint{
arr: [4]uint64{
uint64(v), // bit preserving cast, little endian
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
},
},
}
}

// func IntFromBigint(v bigint) *Int {
// if v > MaxUint256/2-1 {
// panic("I256 IntFromBigint overflow")
// }
// if v < -MaxUint256/2 {
// panic("I256 IntFromBigint underflow")
// }

// if v >= 0 {
// return &Int{v: *FromBigint(v)}
// } else {
// var tmp Int
// tmp.v = *FromBigint(-v)
// tmp.Neg()
// return &tmp
// }

// panic("I256 IntFromBigint not implemented")
// }

// func (x *Int) Bigint() bigint {
// if x.Signum() < 0 {
// return -x.Neg().v.Bigint()
// }
// return x.v.Bigint()

// }

func (x *Int) IsNeg() bool {
return x.Signum() < 0
}

func (x *Int) Add(y *Int, z *Int) *Int {
x.v.Add(&y.v, &z.v)

ys := y.Signum()
zs := z.Signum()

if ys > 0 && zs > 0 && x.Signum() < 0 {
panic("I256 Add overflow")
}

if ys < 0 && zs < 0 && x.Signum() > 0 {
panic("I256 Add underflow")
}

return x
}

func (x *Int) Sub(y *Int, z *Int) *Int {
x.v.UnsafeSub(&y.v, &z.v)

ys := y.Signum()
zs := z.Signum()

if ys > 0 && zs < 0 && x.Signum() < 0 {
panic("I256 Sub overflow")
}

if ys < 0 && zs > 0 && x.Signum() > 0 {
panic("I256 Sub underflow")
}

return x
}

func (x *Int) Mul(y *Int, z *Int) *Int {
x.v.Mul(&y.v, &z.v)

ys := y.Signum()
zs := z.Signum()

if ys > 0 && zs > 0 && x.Signum() < 0 {
panic("I256 Mul overflow #1")
}

if ys < 0 && zs < 0 && x.Signum() < 0 {
panic("I256 Mul overflow #2")
}

if ys > 0 && zs < 0 && x.Signum() > 0 {
panic("I256 Mul underflow #1")
}

if ys < 0 && zs > 0 && x.Signum() > 0 {
panic("I256 Mul underflow #2")
}

return x
}

func (x *Int) Lsh(y *Int, n uint) *Int {
x.v.Lsh(&y.v, n)
return x
}

func (x *Int) Rsh(y *Int, n uint) *Int {
x.v.Rsh(&y.v, n)
return x
}

func (x *Int) Eq(y *Int) bool {
return x.v.Eq(&y.v)
}

func (x *Int) IsZero() bool {
return x.v.IsZero()
}

func (x *Int) Signum() int {
if x.v.arr[3] == 0 && x.v.arr[2] == 0 && x.v.arr[1] == 0 && x.v.arr[0] == 0 {
return 0
}
if x.v.arr[3] < 0x8000000000000000 {
return 1
}
return -1
}

func (x *Int) Gt(y *Int) bool {
xs := x.Signum()
ys := y.Signum()

if xs != ys {
return xs > ys
}
if xs == 0 {
return false
}
if xs > 0 {
return x.v.Gt(&y.v)
}
return y.v.Gt(&x.v)
}

func (x *Int) Lte(y *Int) bool {
return !x.Gt(y)
}

func (x *Int) Gte(y *Int) bool {
xs := x.Signum()
ys := y.Signum()

if xs != ys {
return xs > ys
}
if xs == 0 {
return true
}
if xs > 0 {
return x.v.Gte(&y.v)
}
return y.v.Gte(&x.v)
}

func (x *Int) Int64() int64 {
// TODO: overflow check
if x.v.arr[3] < 0x8000000000000000 {
return int64(x.v.arr[0])
}
// TODO: check if this is correct
return -int64(^x.v.arr[0] + 1)
}

func (x *Int) Abs() *Uint {
if x.Signum() > 0 {
return &x.v
}
x1 := &Int{v: x.v} // so that we don't modify x
return &x1.Neg().v
}

func (x *Int) Neg() *Int {
if x.Signum() == 0 {
return x
}

// twos complement
x.v.Not(&x.v)
x.v.Add(&x.v, &Uint{arr: [4]uint64{1, 0, 0, 0}})
return x
}

func (x *Int) Dec() string {
if x.Signum() < 0 {
return "-" + x.Abs().Dec()
}
return x.Abs().Dec()
}

func (x *Int) Uint() *Uint {
if x.Signum() < 0 {
// panic("I256 Uint negative")
return &x.Neg().v // r3v4_xxx: safe ??
}
return &x.v
}

func (z *Int) Or(x, y *Int) *Int {
z.v.Or(&x.v, &y.v)
return z
}

func (z *Int) NilToZero() *Int {
if z == nil {
z = NewInt(0)
}

return z
}

// Clone creates a new Int identical to z
func (z *Int) Clone() *Int {
var x Int

x.Sub(z, NewInt(0))
return &x
}

// // Clone creates a new Int identical to z
// func (z *Uint) Clone() *Uint {
// var x Uint
// x.arr[0] = z.arr[0]
// x.arr[1] = z.arr[1]
// x.arr[2] = z.arr[2]
// x.arr[3] = z.arr[3]

// return &x
// }
18 changes: 0 additions & 18 deletions main.go

This file was deleted.

6 changes: 6 additions & 0 deletions runtest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package u256

func Hello() uint64 {
x := NewUint(1)
return x.Uint64()
}
Loading

0 comments on commit c4128cb

Please sign in to comment.