Skip to content

Commit

Permalink
add Scan and FromString
Browse files Browse the repository at this point in the history
  • Loading branch information
lukechampine committed Jan 14, 2022
1 parent 1b55fcf commit 526fdb2
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
25 changes: 24 additions & 1 deletion uint128.go
Expand Up @@ -2,6 +2,8 @@ package uint128 // import "lukechampine.com/uint128"

import (
"encoding/binary"
"errors"
"fmt"
"math"
"math/big"
"math/bits"
Expand Down Expand Up @@ -385,6 +387,21 @@ func (u Uint128) Big() *big.Int {
return i
}

// Scan implements fmt.Scanner.
func (u *Uint128) Scan(s fmt.ScanState, ch rune) error {
i := new(big.Int)
if err := i.Scan(s, ch); err != nil {
return err
} else if i.Sign() < 0 {
return errors.New("value cannot be negative")
} else if i.BitLen() > 128 {
return errors.New("value overflows Uint128")
}
u.Lo = i.Uint64()
u.Hi = i.Rsh(i, 64).Uint64()
return nil
}

// New returns the Uint128 value (lo,hi).
func New(lo, hi uint64) Uint128 {
return Uint128{lo, hi}
Expand Down Expand Up @@ -412,6 +429,12 @@ func FromBig(i *big.Int) (u Uint128) {
panic("value overflows Uint128")
}
u.Lo = i.Uint64()
u.Hi = new(big.Int).Rsh(i, 64).Uint64()
u.Hi = i.Rsh(i, 64).Uint64()
return u
}

// FromString parses s as a Uint128 value.
func FromString(s string) (u Uint128, err error) {
_, err = fmt.Sscan(s, &u)
return
}
13 changes: 13 additions & 0 deletions uint128_test.go
Expand Up @@ -287,6 +287,12 @@ func TestString(t *testing.T) {
if x.String() != x.Big().String() {
t.Fatalf("mismatch:\n%v !=\n%v", x.String(), x.Big().String())
}
y, err := FromString(x.String())
if err != nil {
t.Fatal(err)
} else if !y.Equals(x) {
t.Fatalf("mismatch:\n%v !=\n%v", x.String(), y.String())
}
}
// Test 0 string
if Zero.String() != "0" {
Expand All @@ -296,6 +302,13 @@ func TestString(t *testing.T) {
if Max.String() != "340282366920938463463374607431768211455" {
t.Fatalf(`Max.String() should be "0", got %q`, Max.String())
}
// Test parsing invalid strings
if _, err := FromString("-1"); err == nil {
t.Fatal("expected error when parsing -1")
}
if _, err := FromString("340282366920938463463374607431768211456"); err == nil {
t.Fatal("expected error when parsing max+1")
}
}

func BenchmarkArithmetic(b *testing.B) {
Expand Down

0 comments on commit 526fdb2

Please sign in to comment.