// ToBase produces n in base b. For example // // ToBase(2047, 22) -> [1, 5, 4] // // 1 * 22^0 1 // 5 * 22^1 110 // 4 * 22^2 1936 // ---- // 2047 // // ToBase panics for bases < 2. func ToBase(n *big.Int, b int) []int { var nn big.Int nn.Set(n) if b < 2 { panic("invalid base") } k := 1 switch nn.Sign() { case -1: nn.Neg(&nn) k = -1 case 0: return []int{0} } bb := big.NewInt(int64(b)) var r []int rem := big.NewInt(0) for nn.Sign() != 0 { nn.QuoRem(&nn, bb, rem) r = append(r, k*int(rem.Int64())) } return r }
// Encode58 base58 encodes the input. func Encode58(inp []byte) string { num := new(big.Int).SetBytes(inp) buf := make([]byte, 0, len(inp)) base := big.NewInt(int64(58)) rem := new(big.Int) quo := new(big.Int) for num.Sign() != 0 { num, rem = quo.QuoRem(num, base, rem) c := alphabet[rem.Uint64()] buf = append(buf, c) } // Pad leading zeros... for _, c := range inp { if c == 0x0 { buf = append(buf, alphabet[0]) } else { // Stop adding padding after the first nonzero byte. break } } reverseBuf(buf) return string(buf) }
// encodeBlock fills the dst buffer with the encoding of src. // It is assumed the buffers are appropriately sized, and no // bounds checks are performed. In particular, the dst buffer will // be zero-padded from right to left in all remaining bytes. func (enc *Encoding) encodeBlock(dst, src []byte) { // Interpret the block as a big-endian number (Go's default) num := new(big.Int).SetBytes(src) rem := new(big.Int) quo := new(big.Int) encodedLen := enc.EncodedLen(len(src)) // Shift over the given number of extra Bits, so that all of our // wasted bits are on the right. num = num.Lsh(num, enc.extraBits(len(src), encodedLen)) p := encodedLen - 1 for num.Sign() != 0 { num, rem = quo.QuoRem(num, enc.baseBig, rem) dst[p] = enc.encode[rem.Uint64()] p-- } // Pad the remainder of the buffer with 0s for p >= 0 { dst[p] = enc.encode[0] p-- } }
func exec(p []big.Rat, n *big.Int, limit int) { var q, r big.Int rule: for i := 0; i < limit; i++ { fmt.Printf("%d ", n) for j := range p { q.QuoRem(n, p[j].Denom(), &r) if r.BitLen() == 0 { n.Mul(&q, p[j].Num()) continue rule } } break } fmt.Println() }
// encodeBlock fills the dst buffer with the encoding of src. // It is assumed the buffers are appropriately sized, and no // bounds checks are performed. In particular, the dst buffer will // be zero-padded from right to left in all remaining bytes. func (enc *Encoding) encodeBlock(dst, src []byte) { num := new(big.Int).SetBytes(src) rem := new(big.Int) quo := new(big.Int) p := enc.EncodedLen(len(src)) - 1 for num.Sign() != 0 { num, rem = quo.QuoRem(num, enc.baseBig, rem) dst[p] = enc.encode[rem.Uint64()] p-- } // Pad the remainder of the buffer with 0s for p >= 0 { dst[p] = enc.encode[0] p-- } }
func main() { ch := make(chan *big.Int) go fibGen(ch) f, err := os.Open("inp.txt") if err != nil { log.Fatal(err) } defer f.Close() var inp, tmp, mod big.Int fib := make([]big.Int, 1, 50) fib[0] = *(<-ch) fmt.Fscanln(f, &inp) for inp.Sign() >= 0 { minMult := big.NewInt(0).Set(&inp) for i := 0; fib[i].Cmp(&inp) <= 0; i++ { if fib[i].Sign() != 0 { tmp.QuoRem(&inp, &fib[i], &mod) if mod.Sign() == 0 && tmp.Cmp(minMult) == -1 { minMult.Set(&tmp) } } if i == len(fib)-1 { fib = append(fib, *(<-ch)) } } if minMult.Sign() == 0 { minMult.SetInt64(1) } fmt.Println("\nFor num: ", &inp, " i =", minMult) fmt.Print("Series: ") var prnt big.Int for i := 0; i < len(fib) && prnt.Mul(minMult, &fib[i]).Cmp(&inp) <= 0; i++ { fmt.Print(&prnt, " ") } fmt.Println() fmt.Fscanln(f, &inp) } }
// encodeBlock fills the dst buffer with the encoding of src. // It is assumed the buffers are appropriately sized, and no // bounds checks are performed. In particular, the dst buffer will // be zero-padded from right to left in all remaining bytes. func (enc *Encoding) encodeBlock(dst, src []byte) { // Interpret the block as a big-endian number (Go's default) num := new(big.Int).SetBytes(src) rem := new(big.Int) quo := new(big.Int) encodedLen := enc.EncodedLen(len(src)) p := encodedLen - 1 for num.Sign() != 0 { num, rem = quo.QuoRem(num, enc.baseBig, rem) dst[p] = enc.encode[rem.Uint64()] p-- } // Pad the remainder of the buffer with 0s for p >= 0 { dst[p] = enc.encode[0] p-- } }
// b58encode encodes a byte slice b into a base-58 encoded string. func b58encode(b []byte) (s string) { /* See https://en.bitcoin.it/wiki/Base58Check_encoding */ const BITCOIN_BASE58_TABLE = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" /* Convert big endian bytes to big int */ x := new(big.Int).SetBytes(b) /* Initialize */ r := new(big.Int) m := big.NewInt(58) zero := big.NewInt(0) s = "" /* Convert big int to string */ for x.Cmp(zero) > 0 { /* x, r = (x / 58, x % 58) */ x.QuoRem(x, m, r) /* Prepend ASCII character */ s = string(BITCOIN_BASE58_TABLE[r.Int64()]) + s } return s }
// Returns true iff prime is a divisor of 'toFactor' // Else false // *big.Int will refer to an Int, yet is only guaranteed to be // the true quotient if bool is true. func isDivisible(toFactor, prime *big.Int) (bool, *big.Int) { newFactor := new(big.Int) r := new(big.Int) newFactor.QuoRem(toFactor, prime, r) return r.Cmp(ZERO) == 0, newFactor }