PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/onbloc/int256/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
onbloc / int256
Files
12 (gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/onbloc/int256/v0
gno
0.9

Files (12)

  • gnomod.tomltoml
  • arithmetic.gnogno
  • bitwise.gnogno
  • cmp.gnogno
  • conversion.gnogno
  • doc.gnogno
  • int256.gnogno
  • arithmetic_test.gnogno
  • bitwise_test.gnogno
  • cmp_test.gnogno
  • conversion_test.gnogno
  • int256_test.gnogno
  • arithmetic.gnogno
    1package int25623import (4	"gno.land/p/onbloc/uint256/v0"5)67const divisionByZeroError = "division by zero"8

    Functions

    not supported for pure packages by the node (vm/qfuncs)

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    9// Add adds two int256 values and saves the result in z.
    10func (z *Int) Add(x, y *Int) *Int {
    11 z.value.Add(&x.value, &y.value)
    12 return z
    13}
    14
    15// AddUint256 adds int256 and uint256 values and saves the result in z.
    16func (z *Int) AddUint256(x *Int, y *uint256.Uint) *Int {
    17 z.value.Add(&x.value, y)
    18 return z
    19}
    20
    21// Sub subtracts two int256 values and saves the result in z.
    22func (z *Int) Sub(x, y *Int) *Int {
    23 z.value.Sub(&x.value, &y.value)
    24 return z
    25}
    26
    27// SubUint256 subtracts uint256 and int256 values and saves the result in z.
    28func (z *Int) SubUint256(x *Int, y *uint256.Uint) *Int {
    29 z.value.Sub(&x.value, y)
    30 return z
    31}
    32
    33// Mul multiplies two int256 values and saves the result in z.
    34//
    35// It considers the signs of the operands to determine the sign of the result.
    36func (z *Int) Mul(x, y *Int) *Int {
    37 xAbs, xSign := x.Abs(), x.Sign()
    38 yAbs, ySign := y.Abs(), y.Sign()
    39
    40 z.value.Mul(xAbs, yAbs)
    41
    42 if xSign != ySign {
    43 z.value.Neg(&z.value)
    44 }
    45
    46 return z
    47}
    48
    49// Abs returns the absolute value of z.
    50func (z *Int) Abs() *uint256.Uint {
    51 if z.Sign() >= 0 {
    52 return &z.value
    53 }
    54
    55 var absValue uint256.Uint
    56 absValue.Sub(uint0, &z.value).Neg(&z.value)
    57
    58 return &absValue
    59}
    60
    61// Div performs integer division z = x / y and returns z.
    62// If y == 0, it panics with a "division by zero" error.
    63//
    64// This function handles signed division using two's complement representation:
    65// 1. Determine the sign of the quotient based on the signs of x and y.
    66// 2. Perform unsigned division on the absolute values.
    67// 3. Adjust the result's sign if necessary.
    68//
    69// Example visualization for 8-bit integers (scaled down from 256-bit for simplicity):
    70//
    71// Let x = -6 (11111010 in two's complement) and y = 3 (00000011)
    72//
    73// Step 2: Determine signs
    74//
    75// x: negative (MSB is 1)
    76// y: positive (MSB is 0)
    77//
    78// Step 3: Calculate absolute values
    79//
    80// |x| = 6: 11111010 -> 00000110
    81// NOT: 00000101
    82// +1: 00000110
    83//
    84// |y| = 3: 00000011 (already positive)
    85//
    86// Step 4: Unsigned division
    87//
    88// 6 / 3 = 2: 00000010
    89//
    90// Step 5: Adjust sign (x and y have different signs)
    91//
    92// -2: 00000010 -> 11111110
    93// NOT: 11111101
    94// +1: 11111110
    95//
    96// Note: This implementation rounds towards zero, as is standard in Go.
    97func (z *Int) Div(x, y *Int) *Int {
    98 // Step 1: Check for division by zero
    99 if y.IsZero() {
    100 panic(divisionByZeroError)
    101 }
    102
    103 // Step 2, 3: Calculate the absolute values of x and y
    104 xAbs, xSign := x.Abs(), x.Sign()
    105 yAbs, ySign := y.Abs(), y.Sign()
    106
    107 // Step 4: Perform unsigned division on the absolute values
    108 z.value.Div(xAbs, yAbs)
    109
    110 // Step 5: Adjust the sign of the result
    111 // if x and y have different signs, the result must be negative
    112 if xSign != ySign {
    113 z.value.Neg(&z.value)
    114 }
    115
    116 return z
    117}
    118
    119// Example visualization for 8-bit integers (scaled down from 256-bit for simplicity):
    120//
    121// Let x = -7 (11111001 in two's complement) and y = 3 (00000011)
    122//
    123// Step 2: Determine signs
    124//
    125// x: negative (MSB is 1)
    126// y: positive (MSB is 0)
    127//
    128// Step 3: Calculate absolute values
    129//
    130// |x| = 7: 11111001 -> 00000111
    131// NOT: 00000110
    132// +1: 00000111
    133//
    134// |y| = 3: 00000011 (already positive)
    135//
    136// Step 4: Unsigned division
    137//
    138// 7 / 3 = 2: 00000010
    139//
    140// Step 5: Adjust sign (x and y have different signs)
    141//
    142// -2: 00000010 -> 11111110
    143// NOT: 11111101
    144// +1: 11111110
    145//
    146// Final result: -2 (11111110 in two's complement)
    147//
    148// Note: This implementation rounds towards zero, as is standard in Go.
    149func (z *Int) Quo(x, y *Int) *Int {
    150 // Step 1: Check for division by zero
    151 if y.IsZero() {
    152 panic(divisionByZeroError)
    153 }
    154
    155 // Step 2, 3: Calculate the absolute values of x and y
    156 xAbs, xSign := x.Abs(), x.Sign()
    157 yAbs, ySign := y.Abs(), y.Sign()
    158
    159 // perform unsigned division on the absolute values
    160 z.value.Div(xAbs, yAbs)
    161
    162 // Step 5: Adjust the sign of the result
    163 // if x and y have different signs, the result must be negative
    164 if xSign != ySign {
    165 z.value.Neg(&z.value)
    166 }
    167
    168 return z
    169}
    170
    171// Rem sets z to the remainder x%y for y != 0 and returns z.
    172//
    173// The function performs the following steps:
    174// 1. Check for division by zero
    175// 2. Determine the signs of x and y
    176// 3. Calculate the absolute values of x and y
    177// 4. Perform unsigned division and get the remainder
    178// 5. Adjust the sign of the remainder
    179//
    180// Example visualization for 8-bit integers (scaled down from 256-bit for simplicity):
    181//
    182// Let x = -7 (11111001 in two's complement) and y = 3 (00000011)
    183//
    184// Step 2: Determine signs
    185//
    186// x: negative (MSB is 1)
    187// y: positive (MSB is 0)
    188//
    189// Step 3: Calculate absolute values
    190//
    191// |x| = 7: 11111001 -> 00000111
    192// NOT: 00000110
    193// +1: 00000111
    194//
    195// |y| = 3: 00000011 (already positive)
    196//
    197// Step 4: Unsigned division
    198//
    199// 7 / 3 = 2 remainder 1
    200// q = 2: 00000010 (not used in result)
    201// r = 1: 00000001
    202//
    203// Step 5: Adjust sign of remainder (x is negative)
    204//
    205// -1: 00000001 -> 11111111
    206// NOT: 11111110
    207// +1: 11111111
    208//
    209// Final result: -1 (11111111 in two's complement)
    210//
    211// Note: The sign of the remainder is always the same as the sign of the dividend (x).
    212func (z *Int) Rem(x, y *Int) *Int {
    213 // Step 1: Check for division by zero
    214 if y.IsZero() {
    215 panic(divisionByZeroError)
    216 }
    217
    218 // Step 2, 3
    219 xAbs, xSign := x.Abs(), x.Sign()
    220 yAbs := y.Abs()
    221
    222 // Step 4: Perform unsigned division and get the remainder
    223 var q, r uint256.Uint
    224 q.DivMod(xAbs, yAbs, &r)
    225
    226 // Step 5: Adjust the sign of the remainder
    227 if xSign < 0 {
    228 r.Neg(&r)
    229 }
    230
    231 z.value.Set(&r)
    232 return z
    233}
    234
    235// Mod sets z to the modulus x%y for y != 0 and returns z.
    236// The result (z) has the same sign as the divisor y.
    237func (z *Int) Mod(x, y *Int) *Int {
    238 return z.ModE(x, y)
    239}
    240
    241// DivE performs Euclidean division of x by y, setting z to the quotient and returning z.
    242// If y == 0, it panics with a "division by zero" error.
    243//
    244// Euclidean division satisfies the following properties:
    245// 1. The remainder is always non-negative: 0 <= x mod y < |y|
    246// 2. It follows the identity: x = y * (x div y) + (x mod y)
    247func (z *Int) DivE(x, y *Int) *Int {
    248 if y.IsZero() {
    249 panic(divisionByZeroError)
    250 }
    251
    252 // Compute the truncated division quotient
    253 z.Quo(x, y)
    254
    255 // Compute the remainder
    256 r := new(Int).Rem(x, y)
    257
    258 // If the remainder is negative, adjust the quotient
    259 if r.Sign() < 0 {
    260 if y.Sign() > 0 {
    261 z.Sub(z, NewInt(1))
    262 } else {
    263 z.Add(z, NewInt(1))
    264 }
    265 }
    266
    267 return z
    268}
    269
    270// ModE computes the Euclidean modulus of x by y, setting z to the result and returning z.
    271// If y == 0, it panics with a "division by zero" error.
    272//
    273// The Euclidean modulus is always non-negative and satisfies:
    274//
    275// 0 <= x mod y < |y|
    276//
    277// Example visualization for 8-bit integers (scaled down from 256-bit for simplicity):
    278//
    279// Case 1: Let x = -7 (11111001 in two's complement) and y = 3 (00000011)
    280//
    281// Step 1: Compute remainder (using Rem)
    282//
    283// Result of Rem: -1 (11111111 in two's complement)
    284//
    285// Step 2: Adjust sign (result is negative, y is positive)
    286//
    287// -1 + 3 = 2
    288// 11111111 + 00000011 = 00000010
    289//
    290// Final result: 2 (00000010)
    291//
    292// Case 2: Let x = -7 (11111001 in two's complement) and y = -3 (11111101 in two's complement)
    293//
    294// Step 1: Compute remainder (using Rem)
    295//
    296// Result of Rem: -1 (11111111 in two's complement)
    297//
    298// Step 2: Adjust sign (result is negative, y is negative)
    299//
    300// No adjustment needed
    301//
    302// Final result: -1 (11111111 in two's complement)
    303//
    304// Note: This implementation ensures that the result always has the same sign as y,
    305// which is different from the Rem operation.
    306func (z *Int) ModE(x, y *Int) *Int {
    307 if y.IsZero() {
    308 panic(divisionByZeroError)
    309 }
    310
    311 // Perform T-division to get the remainder
    312 z.Rem(x, y)
    313
    314 // Adjust the remainder if necessary
    315 if z.Sign() >= 0 {
    316 return z
    317 }
    318 if y.Sign() > 0 {
    319 return z.Add(z, y)
    320 }
    321
    322 return z.Sub(z, y)
    323}
    324
    325// Sets z to the sum x + y, where z and x are uint256s and y is an int256.
    326//
    327// If the y is positive, it adds y.value to x. otherwise, it subtracts y.Abs() from x.
    328func AddDelta(z, x *uint256.Uint, y *Int) {
    329 if y.Sign() >= 0 {
    330 z.Add(x, &y.value)
    331 } else {
    332 z.Sub(x, y.Abs())
    333 }
    334}
    335
    336// Sets z to the sum x + y, where z and x are uint256s and y is an int256.
    337//
    338// This function returns true if the addition overflows, false otherwise.
    339func AddDeltaOverflow(z, x *uint256.Uint, y *Int) bool {
    340 var overflow bool
    341 if y.Sign() >= 0 {
    342 _, overflow = z.AddOverflow(x, &y.value)
    343 } else {
    344 var absY uint256.Uint
    345 absY.Sub(uint0, &y.value) // absY = -y.value
    346 _, overflow = z.SubOverflow(x, &absY)
    347 }
    348
    349 return overflow
    350}
    351