79 lines
1.4 KiB
Go
79 lines
1.4 KiB
Go
//go:build gmp
|
|
// +build gmp
|
|
|
|
package gmp
|
|
|
|
/*
|
|
#cgo LDFLAGS: -lgmp
|
|
#include <gmp.h>
|
|
#include <stdlib.h>
|
|
*/
|
|
import "C"
|
|
import (
|
|
"math/big"
|
|
)
|
|
|
|
const MaxBase = 62
|
|
|
|
// itoa is like utoa but it prepends a '-' if neg && x != 0.
|
|
func itoa(x []byte, neg bool, base int) string {
|
|
if base < 2 || base > MaxBase {
|
|
panic("invalid base")
|
|
}
|
|
|
|
// x == 0
|
|
if len(x) == 0 {
|
|
return "0"
|
|
}
|
|
// len(x) > 0
|
|
|
|
n := new(big.Int).SetBytes(x)
|
|
if neg {
|
|
n.Neg(n)
|
|
}
|
|
return n.Text(base)
|
|
|
|
}
|
|
|
|
// Text returns the string representation of x in the given base.
|
|
// Base must be between 2 and 62, inclusive. The result uses the
|
|
// lower-case letters 'a' to 'z' for digit values 10 to 35, and
|
|
// the upper-case letters 'A' to 'Z' for digit values 36 to 61.
|
|
// No prefix (such as "0x") is added to the string. If x is a nil
|
|
// pointer it returns "<nil>".
|
|
func (x *Int) Text(base int) string {
|
|
if x == nil {
|
|
return "<nil>"
|
|
}
|
|
nat := x.Bytes()
|
|
|
|
return string(itoa(nat, x.Sign() < 0, base))
|
|
}
|
|
|
|
// Bits return the bits of x
|
|
func (x *Int) Bits() uint {
|
|
// return uint(C.mpz_bitcnt(x.i))
|
|
panic("unimplement")
|
|
}
|
|
|
|
// ToNBytes ouput a bytes to fix n bytes. extend as 0.
|
|
func toNBytes(b *Int, n int) []byte {
|
|
abs := b.Bytes()
|
|
l := len(abs)
|
|
var s []byte
|
|
// l==n is the most case (255/256)
|
|
if l >= n {
|
|
s = abs[l-n : l]
|
|
} else {
|
|
s = make([]byte, n)
|
|
copy(s[n-l:], abs)
|
|
}
|
|
return s
|
|
}
|
|
|
|
func (x *Int) FillBytes(b []byte) []byte {
|
|
bb := toNBytes(x, len(b))
|
|
copy(b, bb)
|
|
return b
|
|
}
|