// SetBytes interprets b as the bytes of a big-endian integer // and sets z to that value. func (z *Int) SetBytes(b []byte) *Int { z.doinit() if len(b) == 0 { z.SetInt64(0) } else { C.mpz_import(&z.i[0], C.size_t(len(b)), 1, 1, 1, 0, unsafe.Pointer(&b[0])) } return z }
// SetUint64 sets z to x and returns z. func (z *Int) SetUint64(x uint64) *Int { z.doinit() // Test for truncation y := C.ulong(x) if uint64(y) == x { C.mpz_set_ui(&z.i[0], y) } else { C.mpz_import(&z.i[0], 1, 0, 8, 0, 0, unsafe.Pointer(&x)) } return z }
// SetInt64 sets z to x and returns z. func (z *Int) SetInt64(x int64) *Int { z.doinit() // Test for truncation y := C.long(x) if int64(y) == x { C.mpz_set_si(&z.i[0], y) } else { negative := false if x < 0 { x = -x negative = true } C.mpz_import(&z.i[0], 1, 0, 8, 0, 0, unsafe.Pointer(&x)) if negative { C.mpz_neg(&z.i[0], &z.i[0]) } } return z }
// Rand sets z to a pseudo-random number in [0, n) and returns z. func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int { z.doinit() // Get rid of n <= 0 case if n.Sign() <= 0 { z.SetInt64(0) return z } // Make a copy of n if aliased t := n aliased := false if n == z { aliased = true t = new(Int).Set(n) } // Work out bit sizes and masks bits := n.BitLen() // >= 1 nwords := (bits + 31) / 32 // >= 1 bitLengthOfMSW := uint(bits % 32) if bitLengthOfMSW == 0 { bitLengthOfMSW = 32 } mask := uint32((1 << bitLengthOfMSW) - 1) words := make([]uint32, nwords) for { // Make a most significant first array of random bytes for i := 0; i < nwords; i++ { words[i] = rnd.Uint32() } // Mask out the top bits so this is only just bigger than n words[0] &= mask C.mpz_import(&z.i[0], C.size_t(len(words)), 1, 4, 0, 0, unsafe.Pointer(&words[0])) // Exit if z < n - should take ~1.5 iterations of loop on average if z.Cmp(t) < 0 { break } } if aliased { t.Clear() } return z }