func arithDivide(a, b *big.Float) (*big.Float, error) { i, acc := b.Int64() if acc == big.Exact && i == 0 { return nil, fmt.Errorf("divide: by zero") } return new(big.Float).Quo(a, b), nil }
func (bed BinaryIntEncoderDecoder) Encode(w io.Writer, n *big.Float) error { if n.IsInt() { x, _ := n.Int64() // TODO - if accuracy is not Exact, then use the other path if err := binary.Write(w, binary.BigEndian, int8(0)); err != nil { return err } return binary.Write(w, binary.BigEndian, x) } else { if err := binary.Write(w, binary.BigEndian, int8(1)); err != nil { return err } exponent := n.MantExp(bed.tmp) f, _ := bed.tmp.Float64() if err := binary.Write(w, binary.BigEndian, f); err != nil { return err } return binary.Write(w, binary.BigEndian, int32(exponent)) } }
// Pow returns a big.Float representation of z**w. Precision is the same as the one // of the first argument. The function panics when z is negative. func Pow(z *big.Float, w *big.Float) *big.Float { if z.Sign() < 0 { panic("Pow: negative base") } // Pow(z, 0) = 1.0 if w.Sign() == 0 { return big.NewFloat(1).SetPrec(z.Prec()) } // Pow(z, 1) = z // Pow(+Inf, n) = +Inf if w.Cmp(big.NewFloat(1)) == 0 || z.IsInf() { return new(big.Float).Copy(z) } // Pow(z, -w) = 1 / Pow(z, w) if w.Sign() < 0 { x := new(big.Float) zExt := new(big.Float).Copy(z).SetPrec(z.Prec() + 64) wNeg := new(big.Float).Neg(w) return x.Quo(big.NewFloat(1), Pow(zExt, wNeg)).SetPrec(z.Prec()) } // w integer fast path if w.IsInt() { wi, _ := w.Int64() return powInt(z, int(wi)) } // compute w**z as exp(z log(w)) x := new(big.Float).SetPrec(z.Prec() + 64) logZ := Log(new(big.Float).Copy(z).SetPrec(z.Prec() + 64)) x.Mul(w, logZ) x = Exp(x) return x.SetPrec(z.Prec()) }
func (bed BinaryVarintEncoderDecoder) Encode(w io.Writer, n *big.Float) error { if n.IsInt() { x, _ := n.Int64() // TODO - if accuracy is not Exact, then use the other path buf := make([]byte, binary.MaxVarintLen64) nBytes := binary.PutVarint(buf, x) if _, err := w.Write([]byte{byte(0)}); err != nil { return err } _, err := w.Write(buf[0:nBytes]) return err } else { if err := binary.Write(w, binary.BigEndian, int8(1)); err != nil { return err } exponent := n.MantExp(bed.tmp) f, _ := bed.tmp.Float64() if err := binary.Write(w, binary.BigEndian, f); err != nil { return err } return binary.Write(w, binary.BigEndian, int32(exponent)) } }