github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/int256/int256.gno (about)

     1  // This package provides a 256-bit signed integer type, Int, and associated functions.
     2  package int256
     3  
     4  import (
     5  	"gno.land/p/demo/uint256"
     6  )
     7  
     8  var one = uint256.NewUint(1)
     9  
    10  type Int struct {
    11  	abs *uint256.Uint
    12  	neg bool
    13  }
    14  
    15  // Zero returns a new Int set to 0.
    16  func Zero() *Int {
    17  	return NewInt(0)
    18  }
    19  
    20  // One returns a new Int set to 1.
    21  func One() *Int {
    22  	return NewInt(1)
    23  }
    24  
    25  // Sign returns:
    26  //
    27  //	-1 if x <  0
    28  //	 0 if x == 0
    29  //	+1 if x >  0
    30  func (z *Int) Sign() int {
    31  	z.initiateAbs()
    32  
    33  	if z.abs.IsZero() {
    34  		return 0
    35  	}
    36  	if z.neg {
    37  		return -1
    38  	}
    39  	return 1
    40  }
    41  
    42  // New returns a new Int set to 0.
    43  func New() *Int {
    44  	return &Int{
    45  		abs: new(uint256.Uint),
    46  	}
    47  }
    48  
    49  // NewInt allocates and returns a new Int set to x.
    50  func NewInt(x int64) *Int {
    51  	return New().SetInt64(x)
    52  }
    53  
    54  // FromDecimal returns a new Int from a decimal string.
    55  // Returns a new Int and an error if the string is not a valid decimal.
    56  func FromDecimal(s string) (*Int, error) {
    57  	return new(Int).SetString(s)
    58  }
    59  
    60  // MustFromDecimal returns a new Int from a decimal string.
    61  // Panics if the string is not a valid decimal.
    62  func MustFromDecimal(s string) *Int {
    63  	z, err := FromDecimal(s)
    64  	if err != nil {
    65  		panic(err)
    66  	}
    67  	return z
    68  }
    69  
    70  // SetString sets s to the value of z and returns z and a boolean indicating success.
    71  func (z *Int) SetString(s string) (*Int, error) {
    72  	neg := false
    73  	// Remove max one leading +
    74  	if len(s) > 0 && s[0] == '+' {
    75  		neg = false
    76  		s = s[1:]
    77  	}
    78  
    79  	if len(s) > 0 && s[0] == '-' {
    80  		neg = true
    81  		s = s[1:]
    82  	}
    83  	var (
    84  		abs *uint256.Uint
    85  		err error
    86  	)
    87  	abs, err = uint256.FromDecimal(s)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	return &Int{
    93  		abs,
    94  		neg,
    95  	}, nil
    96  }
    97  
    98  // FromUint256 is a convenience-constructor from uint256.Uint.
    99  // Returns a new Int and whether overflow occurred.
   100  // OBS: If u is `nil`, this method returns `nil, false`
   101  func FromUint256(x *uint256.Uint) *Int {
   102  	if x == nil {
   103  		return nil
   104  	}
   105  	z := Zero()
   106  
   107  	z.SetUint256(x)
   108  	return z
   109  }
   110  
   111  // OBS, differs from original mempooler int256
   112  // NilToZero sets z to 0 and return it if it's nil, otherwise it returns z
   113  func (z *Int) NilToZero() *Int {
   114  	if z == nil {
   115  		return NewInt(0)
   116  	}
   117  	return z
   118  }
   119  
   120  // initiateAbs sets default value for `z` or `z.abs` value if is nil
   121  // OBS: differs from mempooler int256. It checks not only `z.abs` but also `z`
   122  func (z *Int) initiateAbs() {
   123  	if z == nil || z.abs == nil {
   124  		z.abs = new(uint256.Uint)
   125  	}
   126  }