more clearly correct to tweak the algorithm a little bit.

The state you care about for rounding floating point numbers accurately

is:

1) The bits of computed mantissa.

2) The first bit of the remainder fraction.

3) Whether any of the rest of the bits in the remainder are zero.

My suggestion is to generate 54 bits of mantissa, a combination of 1+2.

(That is, the low bit of the quotient is going to be used for rounding

and

then thrown away.)

Choose q, r, exp such that

(q + r/b) * 2^(exp-1) = a/b

q in [1<<53, 1<<54)

// Handle denormal loss of precision by moving more into remainder.

haveR := r > 0

if denormal {

n := bits to drop

haveR = haveR || (q & (1<<n-1)) != 0

q >>= n

}

// Round q, dropping the low bit we've been carrying.

if q&1 != 0 && haveR || q&2 == 0 {

q++

}

q >>= 1

f := math.Ldexp(float64(q), exp)

if neg {

f = -f

}

return f

https://codereview.appspot.com/6930059/diff/11001/src/pkg/math/big/rat.go

File src/pkg/math/big/rat.go (right):

https://codereview.appspot.com/6930059/diff/11001/src/pkg/math/big/rat.go#newcode94

src/pkg/math/big/rat.go:94: switch {

On 2012/12/15 00:17:48, remyoudompheng wrote:

It's really not clear why you shift twice.

// Determine A' and B', such A'/B' = A/B * (1<<shift)

// is in the interval [1<<52, 1<<53).

The first shift makes it possible to use cmp directly.It's really not clear why you shift twice.

// Determine A' and B', such A'/B' = A/B * (1<<shift)

// is in the interval [1<<52, 1<<53).

Otherwise we'd need a custom compare function.

https://codereview.appspot.com/6930059/diff/11001/src/pkg/math/big/rat.go#newcode122

src/pkg/math/big/rat.go:122: // REVIEWERS: what's the recommended memory

discipline here?

This is fine for now.

https://codereview.appspot.com/6930059/diff/11001/src/pkg/math/big/rat.go#newcode193

src/pkg/math/big/rat.go:193: // exact is true iff no approximation was

involved.

we tend not to use iff in docs.

// If z is exactly representable as a float64, Float64 returns

exact=true.

https://codereview.appspot.com/6930059/