// Round rounds z down to n digits of precision and returns z. The result is // undefined if n is less than zero. No rounding will occur if n is zero. // The result of Round will always be within the interval [⌊z⌋, z]. func (z *Big) Round(n int32) *Big { zp := z.Prec() if n <= 0 || int(n) < zp-int(z.scale) || z.form != finite { return z } shift, ok := checked.Sub(int64(zp), int64(n)) if !ok { z.form = inf return z } if shift <= 0 { return z } z.scale -= int32(shift) if z.isCompact() { val, ok := pow.Ten64(shift) if ok { return z.quoAndRound(z.compact, val) } z.mantissa.SetInt64(z.compact) } val := pow.BigTen(shift) return z.quoBigAndRound(&z.mantissa, &val) }
// MulBigPow10 computes 10 * x ** n. // It reuses x. func MulBigPow10(x *big.Int, n int32) *big.Int { if x.Sign() == 0 || n <= 0 { return x } b := pow.BigTen(int64(n)) return x.Mul(x, &b) }
func bigIlog10(x *big.Int) int { // Should be accurate up to as high as we can possibly report. r := int(((int64(x.BitLen()) + 1) * 0x268826A1) >> 31) if BigAbsCmp(*x, pow.BigTen(int64(r))) < 0 { return r } return r + 1 }
// modbig splits b, a scaled decimal, into its integeral and fractional parts. func modbig(b *big.Int, scale int32) (dec *big.Int, frac *big.Int) { if b.Sign() < 0 { dec, frac = modbig(new(big.Int).Neg(b), scale) dec.Neg(dec) frac.Neg(frac) return dec, frac } exp := pow.BigTen(int64(scale)) if exp.Sign() == 0 { return b, new(big.Int) } dec = new(big.Int).Quo(b, &exp) frac = new(big.Int).Mul(dec, &exp) frac = frac.Sub(b, frac) return dec, frac }
// Int returns x as a big.Int, truncating the fractional portion, if any. func (x *Big) Int() *big.Int { var b big.Int if x.isCompact() { b.SetInt64(x.compact) } else { b.Set(&x.mantissa) } if x.scale == 0 { return &b } if x.scale < 0 { return checked.MulBigPow10(&b, -x.scale) } p := pow.BigTen(int64(x.scale)) return b.Div(&b, &p) }