]> Cypherpunks repositories - gostls13.git/commitdiff
big: added a few missing functions:
authorRobert Griesemer <gri@golang.org>
Mon, 12 Jul 2010 23:09:27 +0000 (16:09 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 12 Jul 2010 23:09:27 +0000 (16:09 -0700)
- sign to determine if a value is < 0, == 0, > 0
- abs to compute absolute value
- Rat.IsInt to test if a rational number is representable as an integer

R=rsc
CC=golang-dev
https://golang.org/cl/1761042

src/pkg/big/int.go
src/pkg/big/int_test.go
src/pkg/big/rat.go
src/pkg/big/rat_test.go

index f16c0d93a79ae80fef27d1726bd17fe617fc75cd..e7ba4021ef18d249666db47544aa152bf7285695 100755 (executable)
@@ -20,6 +20,23 @@ type Int struct {
 var intOne = &Int{false, natOne}
 
 
+// Sign returns:
+//
+//     -1 if x <  0
+//      0 if x == 0
+//     +1 if x >  0
+//
+func (x *Int) Sign() int {
+       if len(x.abs) == 0 {
+               return 0
+       }
+       if x.neg {
+               return -1
+       }
+       return 1
+}
+
+
 // SetInt64 sets z to x and returns z.
 func (z *Int) SetInt64(x int64) *Int {
        neg := false
@@ -47,6 +64,14 @@ func (z *Int) Set(x *Int) *Int {
 }
 
 
+// Abs sets z to |x| (the absolute value of x) and returns z.
+func (z *Int) Abs(x *Int) *Int {
+       z.abs = z.abs.set(x.abs)
+       z.neg = false
+       return z
+}
+
+
 // Neg sets z to -x and returns z.
 func (z *Int) Neg(x *Int) *Int {
        z.abs = z.abs.set(x.abs)
index 82b5417dae6f3d9d7d2e764fb5a766639163b9e8..66379ca1ba866104747c5d1b82f38d47bac2f36d 100755 (executable)
@@ -47,6 +47,18 @@ var prodZZ = []argZZ{
 }
 
 
+func TestSignZ(t *testing.T) {
+       var zero Int
+       for _, a := range sumZZ {
+               s := a.z.Sign()
+               e := a.z.Cmp(&zero)
+               if s != e {
+                       t.Errorf("got %d; want %d for z = %v", s, e, a.z)
+               }
+       }
+}
+
+
 func TestSetZ(t *testing.T) {
        for _, a := range sumZZ {
                var z Int
@@ -61,6 +73,23 @@ func TestSetZ(t *testing.T) {
 }
 
 
+func TestAbsZ(t *testing.T) {
+       var zero Int
+       for _, a := range sumZZ {
+               var z Int
+               z.Abs(a.z)
+               var e Int
+               e.Set(a.z)
+               if e.Cmp(&zero) < 0 {
+                       e.Sub(&zero, &e)
+               }
+               if z.Cmp(&e) != 0 {
+                       t.Errorf("got z = %v; want %v", z, e)
+               }
+       }
+}
+
+
 func testFunZZ(t *testing.T, msg string, f funZZ, a argZZ) {
        var z Int
        f(&z, a.x, a.y)
index c465ab86bf286481bfa2d02dc9c149039b0aa876..d8d6dc4beed68f4fd7ac2587a29053b13fc0354f 100644 (file)
@@ -60,6 +60,23 @@ func (z *Rat) SetInt64(x int64) *Rat {
 }
 
 
+// Sign returns:
+//
+//     -1 if x <  0
+//      0 if x == 0
+//     +1 if x >  0
+//
+func (x *Rat) Sign() int {
+       return x.a.Sign()
+}
+
+
+// IsInt returns true if the denominator of x is 1.
+func (x *Rat) IsInt() bool {
+       return len(x.b) == 1 && x.b[0] == 1
+}
+
+
 // Num returns the numerator of z; it may be <= 0.
 // The result is a reference to z's numerator; it
 // may change if a new value is assigned to z.
@@ -126,6 +143,14 @@ func (x *Rat) Cmp(y *Rat) (r int) {
 }
 
 
+// Abs sets z to |x| (the absolute value of x) and returns z.
+func (z *Rat) Abs(x *Rat) *Rat {
+       z.a.Abs(&x.a)
+       z.b = z.b.set(x.b)
+       return z
+}
+
+
 // Add sets z to the sum x+y and returns z.
 func (z *Rat) Add(x, y *Rat) *Rat {
        a1 := mulNat(&x.a, y.b)
index c74ec857f3a05df48277a646ba4968953b1b69b6..a3793b2e8134f1e32460bbe942d4ef9081c6106f 100644 (file)
@@ -84,6 +84,20 @@ func TestFloatString(t *testing.T) {
 }
 
 
+func TestRatSign(t *testing.T) {
+       zero := NewRat(0, 1)
+       for _, a := range setStringTests {
+               var x Rat
+               x.SetString(a.in)
+               s := x.Sign()
+               e := x.Cmp(zero)
+               if s != e {
+                       t.Errorf("got %d; want %d for z = %v", s, e, &x)
+               }
+       }
+}
+
+
 type ratCmpTest struct {
        rat1, rat2 string
        out        int
@@ -114,6 +128,38 @@ func TestRatCmp(t *testing.T) {
 }
 
 
+func TestIsInt(t *testing.T) {
+       one := NewInt(1)
+       for _, a := range setStringTests {
+               var x Rat
+               x.SetString(a.in)
+               i := x.IsInt()
+               e := x.Denom().Cmp(one) == 0
+               if i != e {
+                       t.Errorf("got %v; want %v for z = %v", i, e, &x)
+               }
+       }
+}
+
+
+func TestRatAbs(t *testing.T) {
+       zero := NewRat(0, 1)
+       for _, a := range setStringTests {
+               var z Rat
+               z.SetString(a.in)
+               var e Rat
+               e.Set(&z)
+               if e.Cmp(zero) < 0 {
+                       e.Sub(zero, &e)
+               }
+               z.Abs(&z)
+               if z.Cmp(&e) != 0 {
+                       t.Errorf("got z = %v; want %v", &z, &e)
+               }
+       }
+}
+
+
 type ratBinFun func(z, x, y *Rat) *Rat
 type ratBinArg struct {
        x, y, z string