github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/utilities/common/math/integer.go (about)

     1  package math
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  )
     7  
     8  const (
     9  	MaxInt8   = 1<<7 - 1
    10  	MinInt8   = -1 << 7
    11  	MaxInt16  = 1<<15 - 1
    12  	MinInt16  = -1 << 15
    13  	MaxInt32  = 1<<31 - 1
    14  	MinInt32  = -1 << 31
    15  	MaxInt64  = 1<<63 - 1
    16  	MinInt64  = -1 << 63
    17  	MaxUint8  = 1<<8 - 1
    18  	MaxUint16 = 1<<16 - 1
    19  	MaxUint32 = 1<<32 - 1
    20  	MaxUint64 = 1<<64 - 1
    21  )
    22  
    23  type HexOrDecimal64 uint64
    24  
    25  func (i *HexOrDecimal64) UnmarshalText(input []byte) error {
    26  	int, ok := ParseUint64(string(input))
    27  	if !ok {
    28  		return fmt.Errorf("invalid hex or decimal integer %q", input)
    29  	}
    30  	*i = HexOrDecimal64(int)
    31  	return nil
    32  }
    33  
    34  func (i HexOrDecimal64) MarshalText() ([]byte, error) {
    35  	return []byte(fmt.Sprintf("%#x", uint64(i))), nil
    36  }
    37  
    38  func ParseUint64(s string) (uint64, bool) {
    39  	if s == "" {
    40  		return 0, true
    41  	}
    42  	if len(s) >= 2 && (s[:2] == "0x" || s[:2] == "0X") {
    43  		v, err := strconv.ParseUint(s[2:], 16, 64)
    44  		return v, err == nil
    45  	}
    46  	v, err := strconv.ParseUint(s, 10, 64)
    47  	return v, err == nil
    48  }
    49  
    50  func MustParseUint64(s string) uint64 {
    51  	v, ok := ParseUint64(s)
    52  	if !ok {
    53  		panic("invalid unsigned 64 bit integer: " + s)
    54  	}
    55  	return v
    56  }
    57  
    58  func SafeSub(x, y uint64) (uint64, bool) {
    59  	return x - y, x < y
    60  }
    61  
    62  func SafeAdd(x, y uint64) (uint64, bool) {
    63  	return x + y, y > MaxUint64-x
    64  }
    65  
    66  func SafeMul(x, y uint64) (uint64, bool) {
    67  	if x == 0 || y == 0 {
    68  		return 0, false
    69  	}
    70  	return x * y, y > MaxUint64/x
    71  }