func TestSqrt(t *testing.T) { tests := []struct { prec uint in float64 }{ {16, 0}, {16, 1}, {16, 4}, {16, 10000}, {16, 2}, {64, 2}, {256, 2}, {1024, 1.5}, } for _, test := range tests { x := new(big.Float).SetPrec(test.prec) x.SetFloat64(test.in) var got, got2, diff big.Float pslq := New(test.prec) pslq.Sqrt(x, &got) got2.SetPrec(test.prec).Mul(&got, &got) diff.Sub(&got2, x) if diff.MinPrec() > 1 { t.Errorf("sqrt(%f) prec %d wrong got %.20f square %.20f expecting %f diff %g minprec %d", test.in, test.prec, &got, &got2, x, &diff, diff.MinPrec()) } } }
func (p *exporter) float(x *Mpflt) { // extract sign (there is no -0) f := &x.Val sign := f.Sign() if sign == 0 { // x == 0 p.int(0) return } // x != 0 // extract exponent such that 0.5 <= m < 1.0 var m big.Float exp := f.MantExp(&m) // extract mantissa as *big.Int // - set exponent large enough so mant satisfies mant.IsInt() // - get *big.Int from mant m.SetMantExp(&m, int(m.MinPrec())) mant, acc := m.Int(nil) if acc != big.Exact { Fatalf("exporter: internal error") } p.int(sign) p.int(exp) p.string(string(mant.Bytes())) }
func (p *exporter) float(x constant.Value) { if x.Kind() != constant.Float { log.Fatalf("gcimporter: unexpected constant %v, want float", x) } // extract sign (there is no -0) sign := constant.Sign(x) if sign == 0 { // x == 0 p.int(0) return } // x != 0 var f big.Float if v, exact := constant.Float64Val(x); exact { // float64 f.SetFloat64(v) } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int { // TODO(gri): add big.Rat accessor to constant.Value. r := valueToRat(num) f.SetRat(r.Quo(r, valueToRat(denom))) } else { // Value too large to represent as a fraction => inaccessible. // TODO(gri): add big.Float accessor to constant.Value. f.SetFloat64(math.MaxFloat64) // FIXME } // extract exponent such that 0.5 <= m < 1.0 var m big.Float exp := f.MantExp(&m) // extract mantissa as *big.Int // - set exponent large enough so mant satisfies mant.IsInt() // - get *big.Int from mant m.SetMantExp(&m, int(m.MinPrec())) mant, acc := m.Int(nil) if acc != big.Exact { log.Fatalf("gcimporter: internal error") } p.int(sign) p.int(exp) p.string(string(mant.Bytes())) }
func emitBig(b *big.Float) string { digits := bits2digits(b.MinPrec()) return b.Text('e', int(digits)) }