25
28
return new(Rat).SetFrac64(a, b)
31
// SetFloat64 sets z to exactly f and returns z.
32
// If f is not finite, SetFloat returns nil.
33
func (z *Rat) SetFloat64(f float64) *Rat {
34
const expMask = 1<<11 - 1
35
bits := math.Float64bits(f)
36
mantissa := bits & (1<<52 - 1)
37
exp := int((bits >> 52) & expMask)
39
case expMask: // non-finite
50
// Optimisation (?): partially pre-normalise.
51
for mantissa&1 == 0 && shift > 0 {
56
z.a.SetUint64(mantissa)
60
z.b.Lsh(&z.b, uint(shift))
62
z.a.Lsh(&z.a, uint(-shift))
67
// isFinite reports whether f represents a finite rational value.
68
// It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0).
69
func isFinite(f float64) bool {
70
return math.Abs(f) <= math.MaxFloat64
73
// low64 returns the least significant 64 bits of natural number z.
74
func low64(z nat) uint64 {
78
if _W == 32 && len(z) > 1 {
79
return uint64(z[1])<<32 | uint64(z[0])
84
// quotToFloat returns the non-negative IEEE 754 double-precision
85
// value nearest to the quotient a/b, using round-to-even in halfway
86
// cases. It does not mutate its arguments.
87
// Preconditions: b is non-zero; a and b have no common factors.
88
func quotToFloat(a, b nat) (f float64, exact bool) {
89
// TODO(adonovan): specialize common degenerate cases: 1.0, integers.
96
panic("division by zero")
99
// 1. Left-shift A or B such that quotient A/B is in [1<<53, 1<<55).
100
// (54 bits if A<B when they are left-aligned, 55 bits if A>=B.)
101
// This is 2 or 3 more than the float64 mantissa field width of 52:
102
// - the optional extra bit is shifted away in step 3 below.
103
// - the high-order 1 is omitted in float64 "normal" representation;
104
// - the low-order 1 will be used during rounding then discarded.
109
if shift := 54 - exp; shift > 0 {
110
a2 = a2.shl(a2, uint(shift))
111
} else if shift < 0 {
112
b2 = b2.shl(b2, uint(-shift))
115
// 2. Compute quotient and remainder (q, r). NB: due to the
116
// extra shift, the low-order bit of q is logically the
117
// high-order bit of r.
119
q, r := q.div(a2, a2, b2) // (recycle a2)
121
haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half
123
// 3. If quotient didn't fit in 54 bits, re-do division by b2<<1
124
// (in effect---we accomplish this incrementally).
125
if mantissa>>54 == 1 {
132
if mantissa>>53 != 1 {
133
panic("expected exactly 54 bits of result")
137
if -1022-52 <= exp && exp <= -1022 {
138
// Denormal case; lose 'shift' bits of precision.
139
shift := uint64(-1022 - (exp - 1)) // [1..53)
140
lostbits := mantissa & (1<<shift - 1)
141
haveRem = haveRem || lostbits != 0
145
// Round q using round-half-to-even.
149
if haveRem || mantissa&2 != 0 {
150
if mantissa++; mantissa >= 1<<54 {
151
// Complete rollover 11...1 => 100...0, so shift is safe
157
mantissa >>= 1 // discard rounding bit. Mantissa now scaled by 2^53.
159
f = math.Ldexp(float64(mantissa), exp-53)
160
if math.IsInf(f, 0) {
166
// Float64 returns the nearest float64 value for x and a bool indicating
167
// whether f represents x exactly. The sign of f always matches the sign
168
// of x, even if f == 0.
169
func (x *Rat) Float64() (f float64, exact bool) {
172
b = b.set(natOne) // materialize denominator
174
f, exact = quotToFloat(x.a.abs, b)
28
181
// SetFrac sets z to a/b and returns z.
29
182
func (z *Rat) SetFrac(a, b *Int) *Rat {
30
183
z.a.neg = a.neg != b.neg
122
275
// IsInt returns true if the denominator of x is 1.
123
276
func (x *Rat) IsInt() bool {
124
return len(x.b) == 0 || x.b.cmp(natOne) == 0
277
return len(x.b.abs) == 0 || x.b.abs.cmp(natOne) == 0
127
280
// Num returns the numerator of x; it may be <= 0.
128
281
// The result is a reference to x's numerator; it
129
// may change if a new value is assigned to x.
282
// may change if a new value is assigned to x, and vice versa.
283
// The sign of the numerator corresponds to the sign of x.
130
284
func (x *Rat) Num() *Int {
134
288
// Denom returns the denominator of x; it is always > 0.
135
289
// The result is a reference to x's denominator; it
136
// may change if a new value is assigned to x.
290
// may change if a new value is assigned to x, and vice versa.
137
291
func (x *Rat) Denom() *Int {
139
return &Int{abs: nat{1}}
141
return &Int{abs: x.b}
144
func gcd(x, y nat) nat {
145
// Euclidean algorithm.
151
_, r = q.div(r, a, b)
292
x.b.neg = false // the result is always >= 0
293
if len(x.b.abs) == 0 {
294
x.b.abs = x.b.abs.set(natOne) // materialize denominator
158
299
func (z *Rat) norm() *Rat {
160
301
case len(z.a.abs) == 0:
161
302
// z == 0 - normalize sign and denominator
304
z.b.abs = z.b.abs.make(0)
305
case len(z.b.abs) == 0:
165
306
// z is normalized int - nothing to do
166
case z.b.cmp(natOne) == 0:
307
case z.b.abs.cmp(natOne) == 0:
167
308
// z is int - normalize denominator
309
z.b.abs = z.b.abs.make(0)
170
if f := gcd(z.a.abs, z.b); f.cmp(natOne) != 0 {
171
z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f)
172
z.b, _ = z.b.div(nil, z.b, f)
314
if f := NewInt(0).binaryGCD(&z.a, &z.b); f.Cmp(intOne) != 0 {
315
z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f.abs)
316
z.b.abs, _ = z.b.abs.div(nil, z.b.abs, f.abs)
317
if z.b.abs.cmp(natOne) == 0 {
318
// z is int - normalize denominator
319
z.b.abs = z.b.abs.make(0)
209
358
func (x *Rat) Cmp(y *Rat) int {
210
return scaleDenom(&x.a, y.b).Cmp(scaleDenom(&y.a, x.b))
359
return scaleDenom(&x.a, y.b.abs).Cmp(scaleDenom(&y.a, x.b.abs))
213
362
// Add sets z to the sum x+y and returns z.
214
363
func (z *Rat) Add(x, y *Rat) *Rat {
215
a1 := scaleDenom(&x.a, y.b)
216
a2 := scaleDenom(&y.a, x.b)
364
a1 := scaleDenom(&x.a, y.b.abs)
365
a2 := scaleDenom(&y.a, x.b.abs)
218
z.b = mulDenom(z.b, x.b, y.b)
367
z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
222
371
// Sub sets z to the difference x-y and returns z.
223
372
func (z *Rat) Sub(x, y *Rat) *Rat {
224
a1 := scaleDenom(&x.a, y.b)
225
a2 := scaleDenom(&y.a, x.b)
373
a1 := scaleDenom(&x.a, y.b.abs)
374
a2 := scaleDenom(&y.a, x.b.abs)
227
z.b = mulDenom(z.b, x.b, y.b)
376
z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
231
380
// Mul sets z to the product x*y and returns z.
232
381
func (z *Rat) Mul(x, y *Rat) *Rat {
233
382
z.a.Mul(&x.a, &y.a)
234
z.b = mulDenom(z.b, x.b, y.b)
383
z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)