Esempio n. 1
0
func (z *Big) quoBig(x, y *Big) *Big {
	scale, ok := checked.Sub32(x.scale, y.scale)
	if !ok {
		z.form = inf
		return z
	}

	zp := z.ctx.prec()
	xp := int32(x.Prec())
	yp := int32(y.Prec())

	// Multiply y by 10 if x' > y'
	if cmpNormBig(&x.mantissa, xp, &y.mantissa, yp) {
		yp--
	}

	scale, ok = checked.Int32(int64(scale) + int64(yp) - int64(xp) + int64(zp))
	if !ok {
		z.form = inf
		return z
	}
	z.scale = scale

	shift, ok := checked.SumSub(zp, yp, xp)
	if !ok {
		z.form = inf
		return z
	}
	if shift > 0 {
		xs := checked.MulBigPow10(new(big.Int).Set(&x.mantissa), shift)
		return z.quoBigAndRound(xs, &y.mantissa)
	}

	// shift < 0
	ns, ok := checked.Sub32(xp, zp)
	if !ok {
		z.form = inf
		return z
	}
	shift, ok = checked.Sub32(ns, yp)
	if !ok {
		z.form = inf
		return z
	}
	ys := checked.MulBigPow10(new(big.Int).Set(&y.mantissa), shift)
	return z.quoBigAndRound(&x.mantissa, ys)
}
Esempio n. 2
0
func shiftRadixRight(x *Big, n int) bool {
	ns, ok := checked.Sub32(x.Scale(), int32(n))
	if !ok {
		return false
	}
	x.SetScale(ns)
	return true
}
Esempio n. 3
0
func (z *Big) quoCompact(x, y *Big) *Big {
	if x.compact == 0 {
		if y.compact == 0 {
			panic(ErrNaN{"division of zero by zero"})
		}
		z.form = 0
		return z
	}

	scale, ok := checked.Sub32(x.scale, y.scale)
	if !ok {
		z.form = inf
		return z
	}

	zp := z.ctx.prec()
	xp := int32(x.Prec())
	yp := int32(y.Prec())

	// Multiply y by 10 if x' > y'
	if cmpNorm(x.compact, xp, y.compact, yp) {
		yp--
	}

	scale, ok = checked.Int32(int64(scale) + int64(yp) - int64(xp) + int64(zp))
	if !ok {
		z.form = inf
		return z
	}
	z.scale = scale

	shift, ok := checked.SumSub(zp, yp, xp)
	if !ok {
		z.form = inf
		return z
	}

	xs, ys := x.compact, y.compact
	if shift > 0 {
		xs, ok = checked.MulPow10(x.compact, shift)
		if !ok {
			x0 := checked.MulBigPow10(big.NewInt(x.compact), shift)
			return z.quoBigAndRound(x0, big.NewInt(y.compact))
		}
		return z.quoAndRound(xs, ys)
	}

	// shift < 0
	ns, ok := checked.Sub32(xp, zp)
	if !ok {
		z.form = inf
		return z
	}

	// new scale == yp, so no inflation needed.
	if ns == yp {
		return z.quoAndRound(xs, ys)
	}
	shift, ok = checked.Sub32(ns, yp)
	if !ok {
		z.form = inf
		return z
	}
	ys, ok = checked.MulPow10(ys, shift)
	if !ok {
		y0 := checked.MulBigPow10(big.NewInt(y.compact), shift)
		return z.quoBigAndRound(big.NewInt(x.compact), y0)
	}
	return z.quoAndRound(xs, ys)
}