Esempio n. 1
0
func (self *Decoder) unsigned_to_signed(x *big.Int, bits uint) *big.Int {
	// return x - ((x >> (bits - 1)) << bits)
	temp := new(big.Int)
	temp.Rsh(x, bits-1)
	temp.Lsh(temp, bits)
	return temp.Sub(x, temp)
}
Esempio n. 2
0
// 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--
	}
}
Esempio n. 3
0
func TestP256BaseMult(t *testing.T) {
	p256 := P256()
	p256Generic := p256.Params()

	scalars := make([]*big.Int, 0, len(p224BaseMultTests)+1)
	for _, e := range p224BaseMultTests {
		k, _ := new(big.Int).SetString(e.k, 10)
		scalars = append(scalars, k)
	}
	k := new(big.Int).SetInt64(1)
	k.Lsh(k, 500)
	scalars = append(scalars, k)

	for i, k := range scalars {
		x, y := p256.ScalarBaseMult(k.Bytes())
		x2, y2 := p256Generic.ScalarBaseMult(k.Bytes())
		if x.Cmp(x2) != 0 || y.Cmp(y2) != 0 {
			t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, x, y, x2, y2)
		}

		if testing.Short() && i > 5 {
			break
		}
	}
}
Esempio n. 4
0
// "stolen" from https://golang.org/pkg/math/big/#Rat.SetFloat64
// Removed non-finite case because we already check for
// Inf/NaN values
func bigIntFromFloat(f float64) *big.Int {
	const expMask = 1<<11 - 1
	bits := math.Float64bits(f)
	mantissa := bits & (1<<52 - 1)
	exp := int((bits >> 52) & expMask)
	if exp == 0 { // denormal
		exp -= 1022
	} else { // normal
		mantissa |= 1 << 52
		exp -= 1023
	}

	shift := 52 - exp

	// Optimization (?): partially pre-normalise.
	for mantissa&1 == 0 && shift > 0 {
		mantissa >>= 1
		shift--
	}

	if shift < 0 {
		shift = -shift
	}

	var a big.Int
	a.SetUint64(mantissa)
	return a.Lsh(&a, uint(shift))
}
Esempio n. 5
0
// Shift returns the result of the shift expression x op s
// with op == token.SHL or token.SHR (<< or >>). x must be
// an Int.
//
func Shift(x Value, op token.Token, s uint) Value {
	switch x := x.(type) {
	case unknownVal:
		return x

	case int64Val:
		if s == 0 {
			return x
		}
		switch op {
		case token.SHL:
			z := big.NewInt(int64(x))
			return normInt(z.Lsh(z, s))
		case token.SHR:
			return x >> s
		}

	case intVal:
		if s == 0 {
			return x
		}
		var z big.Int
		switch op {
		case token.SHL:
			return normInt(z.Lsh(x.val, s))
		case token.SHR:
			return normInt(z.Rsh(x.val, s))
		}
	}

	panic(fmt.Sprintf("invalid shift %v %s %d", x, op, s))
}
Esempio n. 6
0
// number = int_lit [ "p" int_lit ] .
//
func (p *gcParser) parseNumber() Const {
	// mantissa
	sign, val := p.parseInt()
	mant, ok := new(big.Int).SetString(sign+val, 10)
	assert(ok)

	if p.lit == "p" {
		// exponent (base 2)
		p.next()
		sign, val = p.parseInt()
		exp64, err := strconv.ParseUint(val, 10, 0)
		if err != nil {
			p.error(err)
		}
		exp := uint(exp64)
		if sign == "-" {
			denom := big.NewInt(1)
			denom.Lsh(denom, exp)
			return Const{new(big.Rat).SetFrac(mant, denom)}
		}
		if exp > 0 {
			mant.Lsh(mant, exp)
		}
		return Const{new(big.Rat).SetInt(mant)}
	}

	return Const{mant}
}
Esempio n. 7
0
func bigLsh(z, x, y *big.Int) *big.Int {
	i := y.Int64()
	if i < 0 {
		panic("negative shift")
	}
	return z.Lsh(x, uint(i))
}
Esempio n. 8
0
File: util.go Progetto: lumjjb/rabin
func MakeRandom(gen *rand.Rand, degree int) *Polynomial {
	if degree == 0 {
		return NewPolynomialFromInt(gen.Int63n(2))
	}

	coeffs := new(big.Int)
	// x^0 + x^1 + ... + x^n => n + 1 terms
	// However, only the first n terms are variable.  (x^n is fixed to
	// have degree n.)  Thus, we randomly generate the first n terms
	// and fix the final term x^n.
	numBits := degree
	numBlocks := numBits / 32
	for ii := 0; ii < numBlocks; ii++ {
		v := gen.Uint32()

		// Merge.
		bigV := big.NewInt(int64(v))
		coeffs.Lsh(coeffs, 32).Or(coeffs, bigV)
	}
	// Handle the remainder.
	numRemainingBits := uint(numBits % 32)
	if numRemainingBits > 0 {
		mask := (int64(1) << numRemainingBits) - 1
		v := int64(gen.Uint32()) & mask
		coeffs.Lsh(coeffs, numRemainingBits).Or(coeffs, big.NewInt(v))
	}
	coeffs.SetBit(coeffs, degree, 1)
	return NewPolynomial(uint(degree), coeffs)
}
Esempio n. 9
0
// ISqrt returns the greatest number x such that x^2 <= n. n must be
// non-negative.
//
// See https://www.akalin.com/computing-isqrt for an analysis.
func ISqrt(n *big.Int) *big.Int {
	s := n.Sign()
	if s < 0 {
		panic("negative radicand")
	}
	if s == 0 {
		return &big.Int{}
	}

	// x = 2^ceil(Bits(n)/2)
	var x big.Int
	x.Lsh(big.NewInt(1), (uint(n.BitLen())+1)/2)
	for {
		// y = floor((x + floor(n/x))/2)
		var y big.Int
		y.Div(n, &x)
		y.Add(&y, &x)
		y.Rsh(&y, 1)

		if y.Cmp(&x) >= 0 {
			return &x
		}
		x = y
	}
}
Esempio n. 10
0
// CompactToBig converts a compact representation of a whole number N to an
// unsigned 32-bit number.  The representation is similar to IEEE754 floating
// point numbers.
//
// Like IEEE754 floating point, there are three basic components: the sign,
// the exponent, and the mantissa.  They are broken out as follows:
//
//	* the most significant 8 bits represent the unsigned base 256 exponent
// 	* bit 23 (the 24th bit) represents the sign bit
//	* the least significant 23 bits represent the mantissa
//
//	-------------------------------------------------
//	|   Exponent     |    Sign    |    Mantissa     |
//	-------------------------------------------------
//	| 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] |
//	-------------------------------------------------
//
// The formula to calculate N is:
// 	N = (-1^sign) * mantissa * 256^(exponent-3)
//
// This compact form is only used in bitcoin to encode unsigned 256-bit numbers
// which represent difficulty targets, thus there really is not a need for a
// sign bit, but it is implemented here to stay consistent with bitcoind.
func CompactToBig(compact uint32) *big.Int {
	// Extract the mantissa, sign bit, and exponent.
	mantissa := compact & 0x007fffff
	isNegative := compact&0x00800000 != 0
	exponent := uint(compact >> 24)

	// Since the base for the exponent is 256, the exponent can be treated
	// as the number of bytes to represent the full 256-bit number.  So,
	// treat the exponent as the number of bytes and shift the mantissa
	// right or left accordingly.  This is equivalent to:
	// N = mantissa * 256^(exponent-3)
	var bn *big.Int
	if exponent <= 3 {
		mantissa >>= 8 * (3 - exponent)
		bn = big.NewInt(int64(mantissa))
	} else {
		bn = big.NewInt(int64(mantissa))
		bn.Lsh(bn, 8*(exponent-3))
	}

	// Make it negative if the sign bit is set.
	if isNegative {
		bn = bn.Neg(bn)
	}

	return bn
}
Esempio n. 11
0
// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
// returns its double, also in Jacobian form.
func (curve *CurveParams) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
	// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
	delta := new(big.Int).Mul(z, z)
	delta.Mod(delta, curve.P)
	gamma := new(big.Int).Mul(y, y)
	gamma.Mod(gamma, curve.P)
	alpha := new(big.Int).Sub(x, delta)
	if alpha.Sign() == -1 {
		alpha.Add(alpha, curve.P)
	}
	alpha2 := new(big.Int).Add(x, delta)
	alpha.Mul(alpha, alpha2)
	alpha2.Set(alpha)
	alpha.Lsh(alpha, 1)
	alpha.Add(alpha, alpha2)

	beta := alpha2.Mul(x, gamma)

	x3 := new(big.Int).Mul(alpha, alpha)
	beta8 := new(big.Int).Lsh(beta, 3)
	x3.Sub(x3, beta8)
	for x3.Sign() == -1 {
		x3.Add(x3, curve.P)
	}
	x3.Mod(x3, curve.P)

	z3 := new(big.Int).Add(y, z)
	z3.Mul(z3, z3)
	z3.Sub(z3, gamma)
	if z3.Sign() == -1 {
		z3.Add(z3, curve.P)
	}
	z3.Sub(z3, delta)
	if z3.Sign() == -1 {
		z3.Add(z3, curve.P)
	}
	z3.Mod(z3, curve.P)

	beta.Lsh(beta, 2)
	beta.Sub(beta, x3)
	if beta.Sign() == -1 {
		beta.Add(beta, curve.P)
	}
	y3 := alpha.Mul(alpha, beta)

	gamma.Mul(gamma, gamma)
	gamma.Lsh(gamma, 3)
	gamma.Mod(gamma, curve.P)

	y3.Sub(y3, gamma)
	if y3.Sign() == -1 {
		y3.Add(y3, curve.P)
	}
	y3.Mod(y3, curve.P)

	return x3, y3, z3
}
Esempio n. 12
0
//base64ToInt makes int from string.
func base64ToInt(s string) *big.Int {
	var tmp big.Int
	sb := []byte(s)
	for i := len(sb) - 1; i >= 0; i-- {
		b := big.NewInt(base64de[sb[i]])
		tmp.Lsh(&tmp, 6).Or(&tmp, b)
	}
	return &tmp
}
Esempio n. 13
0
func main() {
	i := new(big.Int)

	// 2^1000 == 1 << 1000
	i.SetString("1", 10)
	i.Lsh(i, 1000)

	fmt.Println(misc.DigitSum(i))
}
Esempio n. 14
0
// TestIRootLargeP tests IRoot() with p >= n.BitLen().
func TestIRootLargeP(t *testing.T) {
	var p uint = 100
	var n big.Int
	n.Lsh(big.NewInt(1), p-1)
	r := IRoot(&n, p)
	if r.Cmp(big.NewInt(1)) != 0 {
		t.Errorf("For n=%s and p=%d, expected r=1, got r=%s",
			&n, p, r)
	}
}
Esempio n. 15
0
func p224AlternativeToBig(in *p224FieldElement) *big.Int {
	ret := new(big.Int)
	tmp := new(big.Int)

	for i := uint(0); i < 8; i++ {
		tmp.SetInt64(int64(in[i]))
		tmp.Lsh(tmp, 28*i)
		ret.Add(ret, tmp)
	}
	ret.Mod(ret, p224.P)
	return ret
}
Esempio n. 16
0
// StakePoolTicketFee determines the stake pool ticket fee for a given ticket
// from the passed percentage. Pool fee as a percentage is truncated from 0.01%
// to 100.00%. This all must be done with integers, so bear with the big.Int
// usage below.
//
// See the included doc.go of this package for more information about the
// calculation of this fee.
func StakePoolTicketFee(stakeDiff dcrutil.Amount, relayFee dcrutil.Amount,
	height int32, poolFee float64, params *chaincfg.Params) dcrutil.Amount {
	// Shift the decimal two places, e.g. 1.00%
	// to 100. This assumes that the proportion
	// is already multiplied by 100 to give a
	// percentage, thus making the entirety
	// be a multiplication by 10000.
	poolFeeAbs := math.Floor(poolFee * 100.0)
	poolFeeInt := int64(poolFeeAbs)

	// Subsidy is fetched from the blockchain package, then
	// pushed forward a number of adjustment periods for
	// compensation in gradual subsidy decay. Recall that
	// the average time to claiming 50% of the tickets as
	// votes is the approximately the same as the ticket
	// pool size (params.TicketPoolSize), so take the
	// ceiling of the ticket pool size divided by the
	// reduction interval.
	adjs := int(math.Ceil(float64(params.TicketPoolSize) /
		float64(params.ReductionInterval)))
	initSubsidyCacheOnce.Do(func() {
		subsidyCache = blockchain.NewSubsidyCache(int64(height), params)
	})
	subsidy := blockchain.CalcStakeVoteSubsidy(subsidyCache, int64(height),
		params)
	for i := 0; i < adjs; i++ {
		subsidy *= 100
		subsidy /= 101
	}

	// The numerator is (p*10000*s*(v+z)) << 64.
	shift := uint(64)
	s := new(big.Int).SetInt64(subsidy)
	v := new(big.Int).SetInt64(int64(stakeDiff))
	z := new(big.Int).SetInt64(int64(relayFee))
	num := new(big.Int).SetInt64(poolFeeInt)
	num.Mul(num, s)
	vPlusZ := new(big.Int).Add(v, z)
	num.Mul(num, vPlusZ)
	num.Lsh(num, shift)

	// The denominator is 10000*(s+v).
	// The extra 10000 above cancels out.
	den := new(big.Int).Set(s)
	den.Add(den, v)
	den.Mul(den, new(big.Int).SetInt64(10000))

	// Divide and shift back.
	num.Div(num, den)
	num.Rsh(num, shift)

	return dcrutil.Amount(num.Int64())
}
Esempio n. 17
0
// FactorialS computes n! given an existing swing.Swing object.
//
// It allows multiple factorials to be computed after computing prime numbers
// just once.  The swing.Swing object encapsulates a prime number sieve.
//
// For computing factorials up to n, the swing.Swing object should be
// constructed with with the same or greater n.
//
// FactorialS returns nil if the sieve is not big enough.
func FactorialS(z *big.Int, ps *swing.Swing, n uint) *big.Int {
	var oddFactorial func(*big.Int, uint) *big.Int
	oddFactorial = func(z *big.Int, n uint) *big.Int {
		if n < uint(len(swing.SmallOddFactorial)) {
			return z.SetInt64(swing.SmallOddFactorial[n])
		}

		oddFactorial(z, n/2)
		var os big.Int
		return z.Mul(z.Mul(z, z), ps.OddSwing(&os, n))
	}
	return z.Lsh(oddFactorial(z, n), n-xmath.BitCount32(uint32(n)))
}
Esempio n. 18
0
// trunc truncates a value to the range of the given type.
func (t *_type) trunc(x *big.Int) *big.Int {
	r := new(big.Int)
	m := new(big.Int)
	m.Lsh(one, t.bits)
	m.Sub(m, one)
	r.And(x, m)
	if t.signed && r.Bit(int(t.bits)-1) == 1 {
		m.Neg(one)
		m.Lsh(m, t.bits)
		r.Or(r, m)
	}
	return r
}
Esempio n. 19
0
func main() {
	var n big.Int

	n.SetInt64(1)
	n.Lsh(&n, 1000)

	var sum int
	for _, c := range n.String() {
		sum += int(c - '0')
	}

	fmt.Println(sum)
}
Esempio n. 20
0
File: const.go Progetto: spate/llgo
func binaryIntOp(x *big.Int, op token.Token, y *big.Int) interface{} {
	var z big.Int
	switch op {
	case token.ADD:
		return z.Add(x, y)
	case token.SUB:
		return z.Sub(x, y)
	case token.MUL:
		return z.Mul(x, y)
	case token.QUO:
		return z.Quo(x, y)
	case token.REM:
		return z.Rem(x, y)
	case token.AND:
		return z.And(x, y)
	case token.OR:
		return z.Or(x, y)
	case token.XOR:
		return z.Xor(x, y)
	case token.AND_NOT:
		return z.AndNot(x, y)
	case token.SHL:
		// The shift length must be uint, or untyped int and
		// convertible to uint.
		// TODO 32/64bit
		if y.BitLen() > 32 {
			panic("Excessive shift length")
		}
		return z.Lsh(x, uint(y.Int64()))
	case token.SHR:
		if y.BitLen() > 32 {
			panic("Excessive shift length")
		}
		return z.Rsh(x, uint(y.Int64()))
	case token.EQL:
		return x.Cmp(y) == 0
	case token.NEQ:
		return x.Cmp(y) != 0
	case token.LSS:
		return x.Cmp(y) < 0
	case token.LEQ:
		return x.Cmp(y) <= 0
	case token.GTR:
		return x.Cmp(y) > 0
	case token.GEQ:
		return x.Cmp(y) >= 0
	}
	panic("unreachable")
}
Esempio n. 21
0
func testNegativeInputs(t *testing.T, curve elliptic.Curve, tag string) {
	key, err := GenerateKey(curve, rand.Reader)
	if err != nil {
		t.Errorf("failed to generate key for %q", tag)
	}

	var hash [32]byte
	r := new(big.Int).SetInt64(1)
	r.Lsh(r, 550 /* larger than any supported curve */)
	r.Neg(r)

	if Verify(&key.PublicKey, hash[:], r, r) {
		t.Errorf("bogus signature accepted for %q", tag)
	}
}
func llTest(ps []uint) {
	var s, m big.Int
	one := big.NewInt(1)
	two := big.NewInt(2)
	for _, p := range ps {
		m.Sub(m.Lsh(one, p), one)
		s.SetInt64(4)
		for i := uint(2); i < p; i++ {
			s.Mod(s.Sub(s.Mul(&s, &s), two), &m)
		}
		if s.BitLen() == 0 {
			fmt.Printf("M%d ", p)
		}
	}
}
Esempio n. 23
0
func TestModShift(t *testing.T) {
	A := new(big.Int)
	C := new(big.Int)
	for _, a := range numbers {
		A.SetUint64(a)
		for b := uint8(0); b < 96; b++ {
			c := mod_shift(a, b)
			C.Lsh(A, uint(b))
			C.Mod(C, P)
			expected := C.Uint64()
			if c != expected {
				t.Fatalf("%d << %d: Expecting %d but got %d", a, b, expected, c)
			}
		}
	}
}
Esempio n. 24
0
func maybeCorruptECDSAValue(n *big.Int, typeOfCorruption BadValue, limit *big.Int) *big.Int {
	switch typeOfCorruption {
	case BadValueNone:
		return n
	case BadValueNegative:
		return new(big.Int).Neg(n)
	case BadValueZero:
		return big.NewInt(0)
	case BadValueLimit:
		return limit
	case BadValueLarge:
		bad := new(big.Int).Set(limit)
		return bad.Lsh(bad, 20)
	default:
		panic("unknown BadValue type")
	}
}
Esempio n. 25
0
func TestTrailingOnesBig(t *testing.T) {
	t1 := func(v *big.Int, want int) {
		if got := xmath.TrailingOnesBig(v); got != want {
			t.Fatalf("TrailingOnesBig(0x%x) = %d, want %d", v, got, want)
		}
	}
	// (powers of 2 up to 64) - 1
	// thats 0, 1, 11, 111, and so on.
	var v big.Int
	for p := 0; p < 64; p++ {
		t1(v.SetInt64(1<<uint(p)-1), p)
	}
	// (some bigger powers of 2) - 1
	one := big.NewInt(1)
	for _, p := range []int{64, 100, 1000, 10000} {
		t1(v.Sub(v.Lsh(one, uint(p)), one), p)
	}
}
Esempio n. 26
0
// Factorial computes n!, leaving result in z and returning z.
func Factorial(z *big.Int, n uint) *big.Int {
	currentN := int64(1)
	var product func(*big.Int, uint) *big.Int
	product = func(z *big.Int, n uint) *big.Int {
		switch n {
		case 1:
			currentN += 2
			return z.SetInt64(currentN)
		case 2:
			currentN += 2
			r := currentN
			currentN += 2
			r *= currentN
			return z.SetInt64(r)
		}
		m := n / 2
		var r big.Int
		return z.Mul(product(z, m), product(&r, n-m))
	}

	var p, pr big.Int
	p.SetInt64(1)
	z.SetInt64(1)

	var h, shift uint
	var high uint = 1
	log2n := xmath.Log2(n)

	for h != n {
		shift += h
		h = n >> log2n
		log2n--
		length := high
		high = (h - 1) | 1
		length = (high - length) / 2

		if length > 0 {
			z.Mul(z, p.Mul(&p, product(&pr, length)))
		}
	}

	return z.Lsh(z, shift)
}
Esempio n. 27
0
func TestTrailingZerosBig(t *testing.T) {
	t1 := func(v *big.Int, want int) {
		if got := xmath.TrailingZerosBig(v); got != want {
			t.Fatalf("TrailingZeroBig(0x%x) = %d, want %d", v, got, want)
		}
	}
	// boundary case 0
	t1(&big.Int{}, 0)
	// powers of 2 up to 64
	var v big.Int
	for p := 0; p < 64; p++ {
		t1(v.SetInt64(1<<uint(p)), p)
	}
	// some bigger powers of 2
	one := big.NewInt(1)
	for _, p := range []int{64, 100, 1000, 10000} {
		t1(v.Lsh(one, uint(p)), p)
	}
}
Esempio n. 28
0
func TestModReduce(t *testing.T) {
	MakeNumbers()
	A := new(big.Int)
	B := new(big.Int)
	C := new(big.Int)
	for _, a := range numbers {
		A.SetUint64(a)
		for _, b := range numbers {
			B.SetUint64(b)
			c := mod_reduce(a, b)
			C.Lsh(A, 64)
			C.Add(C, B)
			C.Mod(C, P)
			expected := C.Uint64()
			if c != expected {
				t.Fatalf("mod_reduce(%d,%d): Expecting %d but got %d", a, b, expected, c)
			}
		}
	}
}
Esempio n. 29
0
func main() {
	var n, e, d, bb, ptn, etn, dtn big.Int
	pt := "Rosetta Code"
	fmt.Println("Plain text:            ", pt)

	// a key set big enough to hold 16 bytes of plain text in
	// a single block (to simplify the example) and also big enough
	// to demonstrate efficiency of modular exponentiation.
	n.SetString("9516311845790656153499716760847001433441357", 10)
	e.SetString("65537", 10)
	d.SetString("5617843187844953170308463622230283376298685", 10)

	// convert plain text to a number
	for _, b := range []byte(pt) {
		ptn.Or(ptn.Lsh(&ptn, 8), bb.SetInt64(int64(b)))
	}
	if ptn.Cmp(&n) >= 0 {
		fmt.Println("Plain text message too long")
		return
	}
	fmt.Println("Plain text as a number:", &ptn)

	// encode a single number
	etn.Exp(&ptn, &e, &n)
	fmt.Println("Encoded:               ", &etn)

	// decode a single number
	dtn.Exp(&etn, &d, &n)
	fmt.Println("Decoded:               ", &dtn)

	// convert number to text
	var db [16]byte
	dx := 16
	bff := big.NewInt(0xff)
	for dtn.BitLen() > 0 {
		dx--
		db[dx] = byte(bb.And(&dtn, bff).Int64())
		dtn.Rsh(&dtn, 8)
	}
	fmt.Println("Decoded number as text:", string(db[dx:]))
}
Esempio n. 30
0
// number = int_lit [ "p" int_lit ] .
//
func (p *gcParser) parseNumber() (x operand) {
	x.mode = constant

	// mantissa
	neg, val := p.parseInt()
	mant, ok := new(big.Int).SetString(val, 0)
	assert(ok)
	if neg {
		mant.Neg(mant)
	}

	if p.lit == "p" {
		// exponent (base 2)
		p.next()
		neg, val = p.parseInt()
		exp64, err := strconv.ParseUint(val, 10, 0)
		if err != nil {
			p.error(err)
		}
		exp := uint(exp64)
		if neg {
			denom := big.NewInt(1)
			denom.Lsh(denom, exp)
			x.typ = Typ[UntypedFloat]
			x.val = normalizeRatConst(new(big.Rat).SetFrac(mant, denom))
			return
		}
		if exp > 0 {
			mant.Lsh(mant, exp)
		}
		x.typ = Typ[UntypedFloat]
		x.val = normalizeIntConst(mant)
		return
	}

	x.typ = Typ[UntypedInt]
	x.val = normalizeIntConst(mant)
	return
}