Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

int256 source pure

The int256 package provides a 256-bit signed interger type for gno, supporting arithmetic operations and bitwise mani...

Overview

The int256 package provides a 256-bit signed interger type for gno, supporting arithmetic operations and bitwise manipulation.

It designed for applications that require high-precision arithmetic beyond the standard 64-bit range.

## Features

  • 256-bit Signed Integers: Support for large integer ranging from -2^255 to 2^255-1.
  • Two's Complement Representation: Efficient storage and computation using two's complement.
  • Arithmetic Operations: Add, Sub, Mul, Div, Mod, Inc, Dec, etc.
  • Bitwise Operations: And, Or, Xor, Not, etc.
  • Comparison Operations: Cmp, Eq, Lt, Gt, etc.
  • Conversion Functions: Int to Uint, Uint to Int, etc.
  • String Parsing and Formatting: Convert to and from decimal string representation.

## Notes

  • Some methods may panic when encountering invalid inputs or overflows.
  • The `int256.Int` type can interact with `uint256.Uint` from the `p/demo/uint256` package.
  • Unlike `math/big.Int`, the `int256.Int` type has fixed size (256-bit) and does not support arbitrary precision arithmetic.

Division and modulus operations

This package provides three different division and modulus operations:

  • Div and Rem: Truncated division (T-division)
  • Quo and Mod: Floored division (F-division)
  • DivE and ModE: Euclidean division (E-division)

Truncated division (Div, Rem) is the most common implementation in modern processors and programming languages. It rounds quotients towards zero and the remainder always has the same sign as the dividend.

Floored division (Quo, Mod) always rounds quotients towards negative infinity. This ensures that the modulus is always non-negative for a positive divisor, which can be useful in certain algorithms.

Euclidean division (DivE, ModE) ensures that the remainder is always non-negative, regardless of the signs of the dividend and divisor. This has several mathematical advantages:

  1. It satisfies the unique division with remainder theorem.
  2. It preserves division and modulus properties for negative divisors.
  3. It allows for optimizations in divisions by powers of two.

[+] Currently, ModE and Mod are shared the same implementation.

## Performance considerations:

  • For most operations, the performance difference between these division types is negligible.
  • Euclidean division may require an extra comparison and potentially an addition, which could impact performance in extremely performance-critical scenarios.
  • For divisions by powers of two, Euclidean division can be optimized to use bitwise operations, potentially offering better performance.

## Usage guidelines:

  • Use Div and Rem for general-purpose division that matches most common expectations.
  • Use Quo and Mod when you need a non-negative remainder for positive divisors, or when implementing algorithms that assume floored division.
  • Use DivE and ModE when you need the mathematical properties of Euclidean division, or when working with algorithms that specifically require it.

Note: When working with negative numbers, be aware of the differences in behavior between these division types, especially at the boundaries of integer ranges.

## References

Daan Leijen, “Division and Modulus for Computer Scientists”: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf

Functions 8

func AddDelta

1func AddDelta(z, x *uint256.Uint, y *Int)
source

Sets z to the sum x + y, where z and x are uint256s and y is an int256.

If the y is positive, it adds y.value to x. otherwise, it subtracts y.Abs() from x.

func AddDeltaOverflow

1func AddDeltaOverflow(z, x *uint256.Uint, y *Int) bool
source

Sets z to the sum x + y, where z and x are uint256s and y is an int256.

This function returns true if the addition overflows, false otherwise.

func FromDecimal

1func FromDecimal(s string) (*Int, error)
source

FromDecimal creates a new Int from a decimal string representation. It handles both positive and negative values.

This function is useful for parsing user input or reading numeric data from text-based formats.

func MustFromDecimal

1func MustFromDecimal(s string) *Int
source

MustFromDecimal is similar to FromDecimal but panics if the input string is not a valid decimal representation.

func New

1func New() *Int
source

New creates and returns a new Int initialized to zero.

func NewInt

1func NewInt(x int64) *Int
source

NewInt allocates and returns a new Int set to the value of the provided int64.

func One

1func One() *Int
source

One returns a new Int initialized to one.

This function is convenient for operations that require a unit value, such as incrementing or serving as an identity element in multiplication.

func Zero

1func Zero() *Int
source

Zero returns a new Int initialized to 0.

This function is useful for creating a starting point for calculations or when an explicit zero value is needed.

Types 1

type Int

struct
1type Int struct {
2	value uint256.Uint
3}
source

Methods on Int

func Abs

method on Int
1func (z *Int) Abs() *uint256.Uint
source

Abs returns the absolute value of z.

func Add

method on Int
1func (z *Int) Add(x, y *Int) *Int
source

Add adds two int256 values and saves the result in z.

func AddUint256

method on Int
1func (z *Int) AddUint256(x *Int, y *uint256.Uint) *Int
source

AddUint256 adds int256 and uint256 values and saves the result in z.

func And

method on Int
1func (z *Int) And(x, y *Int) *Int
source

And sets z to the bitwise AND of x and y and returns z.

The bitwise AND operation results in a value that has a bit set only if both corresponding bits of the operands are set.

func Clone

method on Int
1func (z *Int) Clone() *Int
source

Clone creates a new Int identical to z

func Cmp

method on Int
1func (z *Int) Cmp(x *Int) int
source

Cmp compares z and x and returns:

  • 1 if z > x
  • 0 if z == x
  • -1 if z < x

func Div

method on Int
1func (z *Int) Div(x, y *Int) *Int
source

Div performs integer division z = x / y and returns z. If y == 0, it panics with a "division by zero" error.

This function handles signed division using two's complement representation:

  1. Determine the sign of the quotient based on the signs of x and y.
  2. Perform unsigned division on the absolute values.
  3. Adjust the result's sign if necessary.

Example visualization for 8-bit integers (scaled down from 256-bit for simplicity):

Let x = -6 (11111010 in two's complement) and y = 3 (00000011)

Step 2: Determine signs

Example
1x: negative (MSB is 1)
2y: positive (MSB is 0)

Step 3: Calculate absolute values

Example
1|x| = 6:  11111010 -> 00000110
2     NOT: 00000101
3     +1:  00000110
4
5|y| = 3:  00000011 (already positive)

Step 4: Unsigned division

Example
16 / 3 = 2:  00000010

Step 5: Adjust sign (x and y have different signs)

Example
1-2:  00000010 -> 11111110
2     NOT: 11111101
3     +1:  11111110

Note: This implementation rounds towards zero, as is standard in Go.

func DivE

method on Int
1func (z *Int) DivE(x, y *Int) *Int
source

DivE performs Euclidean division of x by y, setting z to the quotient and returning z. If y == 0, it panics with a "division by zero" error.

Euclidean division satisfies the following properties:

  1. The remainder is always non-negative: 0 <= x mod y < |y|
  2. It follows the identity: x = y * (x div y) + (x mod y)

func Eq

method on Int
1func (z *Int) Eq(x *Int) bool
source

func FromUint256

method on Int
1func (z *Int) FromUint256(v *uint256.Uint) *Int
source

FromUint256 sets the Int to the value of the provided Uint256.

This method allows for conversion from unsigned 256-bit integers to signed integers.

func Ge

method on Int
1func (z *Int) Ge(x *Int) bool
source

func Gt

method on Int
1func (z *Int) Gt(x *Int) bool
source

func Int64

method on Int
1func (z *Int) Int64() int64
source

Int64 returns the lower 64-bits of z

func IsNeg

method on Int
1func (z *Int) IsNeg() bool
source

IsNeg returns true if z < 0

func IsZero

method on Int
1func (z *Int) IsZero() bool
source

IsZero returns true if z == 0

func Le

method on Int
1func (z *Int) Le(x *Int) bool
source

func Lsh

method on Int
1func (z *Int) Lsh(x *Int, n uint) *Int
source

Lsh sets z to the result of left-shifting x by n bits and returns z.

Left shift operation moves all bits in the operand to the left by the specified number of positions. Bits shifted out on the left are discarded, and zeros are shifted in on the right.

func Lt

method on Int
1func (z *Int) Lt(x *Int) bool
source

func Mod

method on Int
1func (z *Int) Mod(x, y *Int) *Int
source

Mod sets z to the modulus x%y for y != 0 and returns z. The result (z) has the same sign as the divisor y.

func ModE

method on Int
1func (z *Int) ModE(x, y *Int) *Int
source

ModE computes the Euclidean modulus of x by y, setting z to the result and returning z. If y == 0, it panics with a "division by zero" error.

The Euclidean modulus is always non-negative and satisfies:

Example
10 <= x mod y < |y|

Example visualization for 8-bit integers (scaled down from 256-bit for simplicity):

Case 1: Let x = -7 (11111001 in two's complement) and y = 3 (00000011)

Step 1: Compute remainder (using Rem)

Example
1Result of Rem: -1 (11111111 in two's complement)

Step 2: Adjust sign (result is negative, y is positive)

Example
1-1 + 3 = 2
211111111 + 00000011 = 00000010

Final result: 2 (00000010)

Case 2: Let x = -7 (11111001 in two's complement) and y = -3 (11111101 in two's complement)

Step 1: Compute remainder (using Rem)

Example
1Result of Rem: -1 (11111111 in two's complement)

Step 2: Adjust sign (result is negative, y is negative)

Example
1No adjustment needed

Final result: -1 (11111111 in two's complement)

Note: This implementation ensures that the result always has the same sign as y, which is different from the Rem operation.

func Mul

method on Int
1func (z *Int) Mul(x, y *Int) *Int
source

Mul multiplies two int256 values and saves the result in z.

It considers the signs of the operands to determine the sign of the result.

func Neg

method on Int
1func (z *Int) Neg(x *Int) *Int
source

Neg sets z to -x and returns z.)

func Neq

method on Int
1func (z *Int) Neq(x *Int) bool
source

func NilToZero

method on Int
1func (z *Int) NilToZero() *Int
source

NilToZero returns the Int if it's not nil, or a new zero-valued Int otherwise.

This method is useful for safely handling potentially nil Int pointers, ensuring that operations always have a valid Int to work with.

func Not

method on Int
1func (z *Int) Not(x *Int) *Int
source

Not sets z to the bitwise NOT of x and returns z.

The bitwise NOT operation flips each bit of the operand.

func Or

method on Int
1func (z *Int) Or(x, y *Int) *Int
source

Or sets z to the bitwise OR of x and y and returns z.

The bitwise OR operation results in a value that has a bit set if at least one of the corresponding bits of the operands is set.

func Quo

method on Int
1func (z *Int) Quo(x, y *Int) *Int
source

Example visualization for 8-bit integers (scaled down from 256-bit for simplicity):

Let x = -7 (11111001 in two's complement) and y = 3 (00000011)

Step 2: Determine signs

Example
1x: negative (MSB is 1)
2y: positive (MSB is 0)

Step 3: Calculate absolute values

Example
1|x| = 7:  11111001 -> 00000111
2     NOT: 00000110
3     +1:  00000111
4
5|y| = 3:  00000011 (already positive)

Step 4: Unsigned division

Example
17 / 3 = 2:  00000010

Step 5: Adjust sign (x and y have different signs)

Example
1-2:  00000010 -> 11111110
2     NOT: 11111101
3     +1:  11111110

Final result: -2 (11111110 in two's complement)

Note: This implementation rounds towards zero, as is standard in Go.

func Rem

method on Int
1func (z *Int) Rem(x, y *Int) *Int
source

Rem sets z to the remainder x%y for y != 0 and returns z.

The function performs the following steps:

  1. Check for division by zero
  2. Determine the signs of x and y
  3. Calculate the absolute values of x and y
  4. Perform unsigned division and get the remainder
  5. Adjust the sign of the remainder

Example visualization for 8-bit integers (scaled down from 256-bit for simplicity):

Let x = -7 (11111001 in two's complement) and y = 3 (00000011)

Step 2: Determine signs

Example
1x: negative (MSB is 1)
2y: positive (MSB is 0)

Step 3: Calculate absolute values

Example
1|x| = 7:  11111001 -> 00000111
2     NOT: 00000110
3     +1:  00000111
4
5|y| = 3:  00000011 (already positive)

Step 4: Unsigned division

Example
17 / 3 = 2 remainder 1
2q = 2:  00000010 (not used in result)
3r = 1:  00000001

Step 5: Adjust sign of remainder (x is negative)

Example
1-1:  00000001 -> 11111111
2     NOT: 11111110
3     +1:  11111111

Final result: -1 (11111111 in two's complement)

Note: The sign of the remainder is always the same as the sign of the dividend (x).

func Rsh

method on Int
1func (z *Int) Rsh(x *Int, n uint) *Int
source

Rsh sets z to the result of right-shifting x by n bits and returns z.

Right shift operation moves all bits in the operand to the right by the specified number of positions. Bits shifted out on the right are discarded, and zeros are shifted in on the left.

func Set

method on Int
1func (z *Int) Set(x *Int) *Int
source

Set sets z to x and returns z.

func SetInt64

method on Int
1func (z *Int) SetInt64(v int64) *Int
source

SetInt64 sets the Int to the value of the provided int64.

This method allows for easy conversion from standard Go integer types to Int, correctly handling both positive and negative values.

func SetString

method on Int
1func (z *Int) SetString(s string) (*Int, error)
source

SetString sets the Int to the value represented by the input string. This method supports decimal string representations of integers and handles both positive and negative values.

func SetUint256

method on Int
1func (z *Int) SetUint256(x *uint256.Uint) *Int
source

SetFromUint256 converts a uint256.Uint to Int and sets the value to z.

func SetUint64

method on Int
1func (z *Int) SetUint64(v uint64) *Int
source

SetUint64 sets the Int to the value of the provided uint64.

func Sign

method on Int
1func (z *Int) Sign() int
source

Sign determines the sign of the Int.

It returns -1 for negative numbers, 0 for zero, and +1 for positive numbers.

func String

method on Int
1func (z *Int) String() string
source

ToString returns a string representation of z in base 10. The string is prefixed with a minus sign if z is negative.

func Sub

method on Int
1func (z *Int) Sub(x, y *Int) *Int
source

Sub subtracts two int256 values and saves the result in z.

func SubUint256

method on Int
1func (z *Int) SubUint256(x *Int, y *uint256.Uint) *Int
source

SubUint256 subtracts uint256 and int256 values and saves the result in z.

func Uint64

method on Int
1func (z *Int) Uint64() uint64
source

Uint64 returns the lower 64-bits of z

func Xor

method on Int
1func (z *Int) Xor(x, y *Int) *Int
source

Xor sets z to the bitwise XOR of x and y and returns z.

The bitwise XOR operation results in a value that has a bit set only if the corresponding bits of the operands are different.

Imports 3

Source Files 12