github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/common/math/integer.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:32</date>
    10  //</624342609615130624>
    11  
    12  
    13  package math
    14  
    15  import (
    16  	"fmt"
    17  	"strconv"
    18  )
    19  
    20  //整数限制值。
    21  const (
    22  	MaxInt8   = 1<<7 - 1
    23  	MinInt8   = -1 << 7
    24  	MaxInt16  = 1<<15 - 1
    25  	MinInt16  = -1 << 15
    26  	MaxInt32  = 1<<31 - 1
    27  	MinInt32  = -1 << 31
    28  	MaxInt64  = 1<<63 - 1
    29  	MinInt64  = -1 << 63
    30  	MaxUint8  = 1<<8 - 1
    31  	MaxUint16 = 1<<16 - 1
    32  	MaxUint32 = 1<<32 - 1
    33  	MaxUint64 = 1<<64 - 1
    34  )
    35  
    36  //hexordecimal64将uint64封送为十六进制或十进制。
    37  type HexOrDecimal64 uint64
    38  
    39  //UnmarshalText实现encoding.textUnmarshaller。
    40  func (i *HexOrDecimal64) UnmarshalText(input []byte) error {
    41  	int, ok := ParseUint64(string(input))
    42  	if !ok {
    43  		return fmt.Errorf("invalid hex or decimal integer %q", input)
    44  	}
    45  	*i = HexOrDecimal64(int)
    46  	return nil
    47  }
    48  
    49  //MarshalText实现Encoding.TextMarshaler。
    50  func (i HexOrDecimal64) MarshalText() ([]byte, error) {
    51  	return []byte(fmt.Sprintf("%#x", uint64(i))), nil
    52  }
    53  
    54  //ParseUInt64以十进制或十六进制语法解析为整数。
    55  //可接受前导零。空字符串解析为零。
    56  func ParseUint64(s string) (uint64, bool) {
    57  	if s == "" {
    58  		return 0, true
    59  	}
    60  	if len(s) >= 2 && (s[:2] == "0x" || s[:2] == "0X") {
    61  		v, err := strconv.ParseUint(s[2:], 16, 64)
    62  		return v, err == nil
    63  	}
    64  	v, err := strconv.ParseUint(s, 10, 64)
    65  	return v, err == nil
    66  }
    67  
    68  //mustParseUInt64作为整数进行分析,如果字符串无效,则会恐慌。
    69  func MustParseUint64(s string) uint64 {
    70  	v, ok := ParseUint64(s)
    71  	if !ok {
    72  		panic("invalid unsigned 64 bit integer: " + s)
    73  	}
    74  	return v
    75  }
    76  
    77  //注意:以下方法需要使用位检查或ASM进行优化
    78  
    79  //SAFESUB返回减法结果以及是否发生溢出。
    80  func SafeSub(x, y uint64) (uint64, bool) {
    81  	return x - y, x < y
    82  }
    83  
    84  //safeadd返回结果以及是否发生溢出。
    85  func SafeAdd(x, y uint64) (uint64, bool) {
    86  	return x + y, y > MaxUint64-x
    87  }
    88  
    89  //safemul返回乘法结果以及是否发生溢出。
    90  func SafeMul(x, y uint64) (uint64, bool) {
    91  	if x == 0 || y == 0 {
    92  		return 0, false
    93  	}
    94  	return x * y, y > MaxUint64/x
    95  }
    96