Example #1
0
// 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)
}
Example #2
0
// Int64 returns x as an int64, truncating the fractional portion, if any.
func (x *Big) Int64() int64 {
	var b int64
	if x.isCompact() {
		b = x.compact
	} else {
		b = x.mantissa.Int64()
	}
	if x.scale == 0 {
		return b
	}
	if x.scale < 0 {
		// Undefined. checked.MulPow10 returns 0 when ok is false.
		// IMO, 0 is a better choice than 1 << 64 - 1 because it could cause a
		// division by zero panic which would be a clear indication something is
		// incorrect.
		b, _ = checked.MulPow10(b, -x.scale)
		return b
	}
	p, ok := pow.Ten64(int64(x.scale))
	// See above comment.
	if !ok {
		return 0
	}
	return b / p
}
Example #3
0
// MulPow10 computes 10 * x ** n and a bool indicating whether
// the multiplcation was successful.
func MulPow10(x int64, n int32) (p int64, ok bool) {
	if x == 0 || n <= 0 || x == c.Inflated {
		return x, true
	}
	if n < pow.Tab64Len && n < pow.ThreshLen {
		if x == 1 {
			return pow.Ten64(int64(n))
		}
		if arith.Abs(int64(n)) < pow.Thresh(n) {
			p, ok := pow.Ten64(int64(n))
			if !ok {
				return 0, false
			}
			return Mul(x, p)
		}
	}
	return 0, false
}
Example #4
0
func ilog10(x int64) int {
	// From https://graphics.stanford.edu/~seander/bithacks.html
	t := ((64 - CLZ(x) + 1) * 1233) >> 12
	v, ok := pow.Ten64(int64(t))
	if !ok {
		return bigIlog10(big.NewInt(x))
	}
	if x < v {
		return t
	}
	return t + 1
}
Example #5
0
// mod splits fr, a scaled decimal, into its integeral and fractional parts.
func mod(fr int64, scale int32) (dec int64, frac int64, ok bool) {
	if fr < 0 {
		dec, frac, ok = mod(-fr, scale)
		return -dec, -frac, ok
	}
	exp, ok := pow.Ten64(int64(scale))
	if !ok {
		return 0, 0, false
	}
	if exp == 0 {
		return fr, 0, true
	}
	dec = fr / exp
	frac = fr - (dec * exp)
	return dec, frac, true
}