Skip to content

Commit 7be8e4d

Browse files
committed
add Rat methods SetFrac, Neg, and IsInt
1 parent 12ad828 commit 7be8e4d

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

rat.go

+32
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,20 @@ func (q *Rat) SetUint(x, y uint) *Rat {
9595
return q
9696
}
9797

98+
// SetFrac sets z to a/b and returns z.
99+
func (z *Rat) SetFrac(a, b *Int) *Rat {
100+
a.doinit()
101+
b.doinit()
102+
103+
temp_a := new(Rat).SetInt(a)
104+
temp_b := new(Rat).SetInt(b)
105+
z.Quo(temp_a, temp_b)
106+
temp_a.Clear()
107+
temp_b.Clear()
108+
109+
return z
110+
}
111+
98112
// SetInt sets q to x and returns q.
99113
func (q *Rat) SetInt(x *Int) *Rat {
100114
q.doinit()
@@ -224,6 +238,14 @@ func (q *Rat) Mul(x, y *Rat) *Rat {
224238
return q
225239
}
226240

241+
// Neg sets z to -x and returns z.
242+
func (z *Rat) Neg(x *Rat) *Rat {
243+
z.doinit()
244+
x.doinit()
245+
C.mpq_neg(&z.i[0], &x.i[0])
246+
return z
247+
}
248+
227249
func (q *Rat) Quo(x, y *Rat) *Rat {
228250
x.doinit()
229251
y.doinit()
@@ -294,6 +316,16 @@ func CmpRatInt64(q *Rat, x int64, y uint) int {
294316
//return int(C.mpq_cmp_ui(&x.i[0], C.long(x), C.ulong(y)))
295317
}
296318

319+
// IsInt returns true if the denominator of x is 1.
320+
func (q *Rat) IsInt() bool {
321+
q.doinit()
322+
C.mpq_canonicalize(&q.i[0])
323+
if q.Denom().Cmp(intOne) == 0 {
324+
return true
325+
}
326+
return false
327+
}
328+
297329
// Sign returns:
298330
//
299331
// -1 if x < 0

rat_test.go

+66
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,72 @@ func TestRatCmp(t *testing.T) {
137137
}
138138
}
139139

140+
func TestIsInt(t *testing.T) {
141+
one := NewInt(1)
142+
for _, a := range setStringTests {
143+
x, ok := new(Rat).SetString(a.in)
144+
if !ok {
145+
continue
146+
}
147+
i := x.IsInt()
148+
e := x.Denom().Cmp(one) == 0
149+
if i != e {
150+
t.Errorf("got IsInt(%v) == %v; want %v", x, i, e)
151+
}
152+
}
153+
}
154+
155+
func TestRatAbs(t *testing.T) {
156+
zero := new(Rat)
157+
for _, a := range setStringTests {
158+
x, ok := new(Rat).SetString(a.in)
159+
if !ok {
160+
continue
161+
}
162+
e := new(Rat).Set(x)
163+
if e.Cmp(zero) < 0 {
164+
e.Sub(zero, e)
165+
}
166+
z := new(Rat).Abs(x)
167+
if z.Cmp(e) != 0 {
168+
t.Errorf("got Abs(%v) = %v; want %v", x, z, e)
169+
}
170+
}
171+
}
172+
173+
func TestRatNeg(t *testing.T) {
174+
zero := new(Rat)
175+
for _, a := range setStringTests {
176+
x, ok := new(Rat).SetString(a.in)
177+
if !ok {
178+
continue
179+
}
180+
e := new(Rat).Sub(zero, x)
181+
z := new(Rat).Neg(x)
182+
if z.Cmp(e) != 0 {
183+
t.Errorf("got Neg(%v) = %v; want %v", x, z, e)
184+
}
185+
}
186+
}
187+
188+
func TestRatInv(t *testing.T) {
189+
zero := new(Rat)
190+
for _, a := range setStringTests {
191+
x, ok := new(Rat).SetString(a.in)
192+
if !ok {
193+
continue
194+
}
195+
if x.Cmp(zero) == 0 {
196+
continue // avoid division by zero
197+
}
198+
e := new(Rat).SetFrac(x.Denom(), x.Num())
199+
z := new(Rat).Inv(x)
200+
if z.Cmp(e) != 0 {
201+
t.Errorf("got Inv(%v) = %v; want %v", x, z, e)
202+
}
203+
}
204+
}
205+
140206
type ratBinFun func(z, x, y *Rat) *Rat
141207
type ratBinArg struct {
142208
x, y, z string

0 commit comments

Comments
 (0)