Beispiel #1
0
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
}
Beispiel #2
0
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))
	}
}
Beispiel #3
0
// 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))
	}
}