Pure package detail
int256
gno.land/p/gnoswap/int256
Indexed deployment identity with independently loaded latest RPC source. Functions and Render are realm-only RPC capabilities.
Indexed deployment
Identity
- Package path
- gno.land/p/gnoswap/int256
- Block
- 192929
- Deployed (UTC)
- Transaction
- xhuv++R5x3BqKmGOaWMxzNjYeILidFHJfpKIxzWAXRY=
Latest RPC state
Source
package int256
import (
"errors"
"math/bits"
"strconv"
u256 "gno.land/p/gnoswap/uint256"
)
const (
maxAbsI256Dec = "57896044618658097711785492504343953926634992332820282019728792003956564819968"
maxWords = 256 / bits.UintSize
)
// MUST BE IMMUTABLE, DO NOT MODIFY
// multipliers is a table of multipliers for the decimal conversion.
var _multipliers = [5]*Int{
nil,
{0x8ac7230489e80000, 0, 0, 0},
{0x98a224000000000, 0x4b3b4ca85a86c47a, 0, 0},
{0x4a00000000000000, 0xebfdcb54864ada83, 0x28c87cb5c89a2571, 0},
{0, 0x7775a5f171951000, 0x764b4abe8652979, 0x161bcca7119915b5},
}
func FromDecimal(decimal string) (*Int, error) {
z, err := new(Int).SetString(decimal)
if err != nil {
return nil, err
}
return z, nil
}
func MustFromDecimal(decimal string) *Int {
z, err := FromDecimal(decimal)
if err != nil {
panic(err)
}
return z
}
func (z *Int) ToString() string {
s := z.Sign()
if s == 0 {
return "0"
}
if z.IsInt64() {
return strconv.FormatInt(z.Int64(), 10)
}
y := new(Int)
if s > 0 {
y.Set(z)
} else {
y.Neg(z)
}
var (
out = []byte("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
divisor = new(Int).SetUint64(10000000000000000000)
pos = len(out)
buf = make([]byte, 0, 19)
)
for {
var quot Int
rem := udivrem(quot[:], y[:], divisor)
y.Set(")
buf = strconv.AppendUint(buf[:0], rem.Uint64(), 10)
copy(out[pos-len(buf):], buf)
if y.IsZero() {
break
}
pos -= 19
}
var res string
if s < 0 {
res = "-"
}
res += string(out[pos-len(buf):])
return res
}
func (z *Int) SetString(s string) (*Int, error) {
if len(s) == 0 {
return nil, errors.New("int256: empty string")
}
isNeg := false
switch s[0] {
case '+':
s = s[1:]
case '-':
isNeg = true
s = s[1:]
}
if len(s) == 0 {
return nil, errors.New("int256: empty string")
}
// Parallel comparison technique for validation
// Process in 8-byte chunks for optimal performance
sLen := len(s)
i := 0
// Process 8 bytes at a time
for i+7 < sLen {
// Access up to s[i+7] is safe, then we can reduce the number of bounds checks
_ = s[i+7]
// Convert 8 bytes into a single uint64
// This method processes bytes directly, so no endianness issues
chunk := uint64(s[i]) | uint64(s[i+1])<<8
chunk |= uint64(s[i+2])<<16 | uint64(s[i+3])<<24
chunk |= uint64(s[i+4])<<32 | uint64(s[i+5])<<40
chunk |= uint64(s[i+6])<<48 | uint64(s[i+7])<<56
// Check for '+' (0x2B) using SWAR technique
// Subtracting 0x2B from each byte makes '+' bytes become 0
// Subtracting 0x01 makes bytes in ASCII range (0-127) have 0 in their highest bit
// Therefore, AND with 0x80 to check for zero bytes
plusTest := ((chunk ^ 0x2B2B2B2B2B2B2B2B) - 0x0101010101010101) & 0x8080808080808080
// Check for '-' (0x2D) using SWAR technique
minusTest := ((chunk ^ 0x2D2D2D2D2D2D2D2D) - 0x0101010101010101) & 0x8080808080808080
// If either test is non-zero, a sign character exists
if (plusTest | minusTest) != 0 {
return nil, errors.New("int256: invalid sign in middle of number")
}
i += 8
}
// Process remaining bytes
for ; i < sLen; i++ {
if s[i] == '+' || s[i] == '-' {
return nil, errors.New("int256: invalid sign in middle of number")
}
}
// Strip leading zeros
if len(s) > 0 && s[0] == '0' {
idx := 0
for idx < len(s) && s[idx] == '0' {
idx++
}
s = s[idx:]
// If all characters were zeros, set to "0"
if len(s) == 0 {
s = "0"
}
}
// Check for overflow
if len(s) > len(maxAbsI256Dec) ||
(len(s) == len(maxAbsI256Dec) && s > maxAbsI256Dec) ||
(s == maxAbsI256Dec && !isNeg) {
return nil, errors.New("int256: overflow")
}
if err := z.fromDecimal(s); err != nil {
return nil, err
}
if isNeg {
z.Neg(z)
}
return z, nil
}
func (z *Int) fromDecimal(bs string) error {
z.Clear()
var (
num uint64
err error
remaining = len(bs)
)
if remaining == 0 {
return errors.New("EOF")
}
for i, mult := range _multipliers {
if remaining <= 0 {
return nil
}
if remaining > 19 {
num, err = strconv.ParseUint(bs[remaining-19:remaining], 10, 64)
} else {
num, err = strconv.ParseUint(bs, 10, 64)
}
if err != nil {
return err
}
if i == 0 {
z.SetUint64(num)
} else {
base := new(Int).SetUint64(num)
z.Add(z, base.Mul(base, mult))
}
if remaining > 19 {
bs = bs[0 : remaining-19]
}
remaining -= 19
}
return nil
}
// FromUint256 converts a uint256 to int256.
// Panics if the uint256 value is greater than MaxInt256 (2^255 - 1).
func FromUint256(x *u256.Uint) *Int {
// Check overflow: if MSB of x[3] is set, value > MaxInt256
if x[3] > 0x7fffffffffffffff {
panic("int256: overflow - uint256 value exceeds MaxInt256")
}
z := &Int{}
z[0] = x[0]
z[1] = x[1]
z[2] = x[2]
z[3] = x[3]
return z
}
The verified vm/qfuncs operation accepts realm paths only.
Pure packages expose source files but do not have Realm Render.