big: added a few missing functions:

- 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
This commit is contained in:
Robert Griesemer 2010-07-12 16:09:27 -07:00
parent bebd22f8e0
commit 97bcf049f7
4 changed files with 125 additions and 0 deletions

View File

@ -20,6 +20,23 @@ type Int struct {
var intOne = &Int{false, natOne} 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. // SetInt64 sets z to x and returns z.
func (z *Int) SetInt64(x int64) *Int { func (z *Int) SetInt64(x int64) *Int {
neg := false 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. // Neg sets z to -x and returns z.
func (z *Int) Neg(x *Int) *Int { func (z *Int) Neg(x *Int) *Int {
z.abs = z.abs.set(x.abs) z.abs = z.abs.set(x.abs)

View File

@ -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) { func TestSetZ(t *testing.T) {
for _, a := range sumZZ { for _, a := range sumZZ {
var z Int 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) { func testFunZZ(t *testing.T, msg string, f funZZ, a argZZ) {
var z Int var z Int
f(&z, a.x, a.y) f(&z, a.x, a.y)

View 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. // Num returns the numerator of z; it may be <= 0.
// The result is a reference to z's numerator; it // The result is a reference to z's numerator; it
// may change if a new value is assigned to z. // 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. // Add sets z to the sum x+y and returns z.
func (z *Rat) Add(x, y *Rat) *Rat { func (z *Rat) Add(x, y *Rat) *Rat {
a1 := mulNat(&x.a, y.b) a1 := mulNat(&x.a, y.b)

View 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 { type ratCmpTest struct {
rat1, rat2 string rat1, rat2 string
out int 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 ratBinFun func(z, x, y *Rat) *Rat
type ratBinArg struct { type ratBinArg struct {
x, y, z string x, y, z string