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) }
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) }