// BitLen returns the absolute value of x in bits. func (x *Big) BitLen() int { // If using an artificially inflated number determine the // bitlen using the number of digits. // // http://www.exploringbinary.com/number-of-bits-in-a-decimal-integer/ if x.scale < 0 { // Number of zeros in scale + digits in z. d := -int(x.scale) + x.Prec() return int(math.Ceil(float64(d-1) * ln210)) } if x.isCompact() { return arith.BitLen(x.compact) } return x.mantissa.BitLen() }
// Sqrt sets z to the square root of x and returns z. // The precision of Sqrt is determined by z's Context. // Sqrt will panic on negative values since Big cannot // represent imaginary numbers. func (z *Big) Sqrt(x *Big) *Big { if x.SignBit() { panic("math.Sqrt: cannot take square root of negative number") } switch { case x.form == inf: z.form = inf return z case x.Sign() == 0: z.form = zero return z } // First fast path---check if x is a perfect square. If it is, we can avoid // having to inflate x and can possibly use can use the hardware SQRT. // Note that we can only catch perfect squares that aren't big.Ints. if sq, ok := perfectSquare(x); ok { z.ctx = x.ctx return z.SetMantScale(sq, 0) } zp := z.ctx.prec() // Temporary inflation. Should be enough to accurately determine the sqrt // with at least zp digits after the radix. zpadj := int(zp) << 1 var tmp *Big if z != x { zctx := z.ctx tmp = z.Set(x) tmp.ctx = zctx } else { tmp = new(Big).Set(x) } if !shiftRadixRight(tmp, zpadj) { z.form = inf return z } // Second fast path. Check to see if we can calculate the square root without // using big.Int if !x.IsBig() && zpadj <= 19 { n := tmp.Int64() ix := n >> uint((arith.BitLen(n)+1)>>1) var p int64 for { p = ix ix += n / ix ix >>= 1 if ix == p { return z.SetMantScale(ix, zp) } } } // x isn't a perfect square or x is a big.Int n := tmp.Int() ix := new(big.Int).Rsh(n, uint((n.BitLen()+1)>>1)) var a, p big.Int for { p.Set(ix) ix.Add(ix, a.Quo(n, ix)).Rsh(ix, 1) if ix.Cmp(&p) == 0 { return z.SetBigMantScale(ix, zp) } } }