github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/common/math/integer.go (about)

     1  package math
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  )
     7  
     8  const (
     9  	// Integer limit values.
    10  	MaxInt8   = 1<<7 - 1
    11  	MinInt8   = -1 << 7
    12  	MaxInt16  = 1<<15 - 1
    13  	MinInt16  = -1 << 15
    14  	MaxInt32  = 1<<31 - 1
    15  	MinInt32  = -1 << 31
    16  	MaxInt64  = 1<<63 - 1
    17  	MinInt64  = -1 << 63
    18  	MaxUint8  = 1<<8 - 1
    19  	MaxUint16 = 1<<16 - 1
    20  	MaxUint32 = 1<<32 - 1
    21  	MaxUint64 = 1<<64 - 1
    22  )
    23  
    24  // HexOrDecimal64 marshals uint64 as hex or decimal.
    25  type HexOrDecimal64 uint64
    26  
    27  // UnmarshalText implements encoding.TextUnmarshaler.
    28  func (i *HexOrDecimal64) UnmarshalText(input []byte) error {
    29  	int, ok := ParseUint64(string(input))
    30  	if !ok {
    31  		return fmt.Errorf("invalid hex or decimal integer %q", input)
    32  	}
    33  	*i = HexOrDecimal64(int)
    34  	return nil
    35  }
    36  
    37  // MarshalText implements encoding.TextMarshaler.
    38  func (i HexOrDecimal64) MarshalText() ([]byte, error) {
    39  	return []byte(fmt.Sprintf("%#x", uint64(i))), nil
    40  }
    41  
    42  // ParseUint64 parses s as an integer in decimal or hexadecimal syntax.
    43  // Leading zeros are accepted. The empty string parses as zero.
    44  func ParseUint64(s string) (uint64, bool) {
    45  	if s == "" {
    46  		return 0, true
    47  	}
    48  	if len(s) >= 2 && (s[:2] == "0x" || s[:2] == "0X") {
    49  		v, err := strconv.ParseUint(s[2:], 16, 64)
    50  		return v, err == nil
    51  	}
    52  	v, err := strconv.ParseUint(s, 10, 64)
    53  	return v, err == nil
    54  }
    55  
    56  // MustParseUint64 parses s as an integer and panics if the string is invalid.
    57  func MustParseUint64(s string) uint64 {
    58  	v, ok := ParseUint64(s)
    59  	if !ok {
    60  		panic("invalid unsigned 64 bit integer: " + s)
    61  	}
    62  	return v
    63  }
    64  
    65  // NOTE: The following methods need to be optimised using either bit checking or asm
    66  
    67  // SafeSub returns subtraction result and whether overflow occurred.
    68  func SafeSub(x, y uint64) (uint64, bool) {
    69  	return x - y, x < y
    70  }
    71  
    72  // SafeAdd returns the result and whether overflow occurred.
    73  func SafeAdd(x, y uint64) (uint64, bool) {
    74  	return x + y, y > MaxUint64-x
    75  }
    76  
    77  // SafeMul returns multiplication result and whether overflow occurred.
    78  func SafeMul(x, y uint64) (uint64, bool) {
    79  	if x == 0 || y == 0 {
    80  		return 0, false
    81  	}
    82  	return x * y, y > MaxUint64/x
    83  }