github.com/FUSIONFoundation/efsn@v3.6.2-0.20200916075423-dbb5dd5d2cc7+incompatible/common/overflow/overflow.go (about)

     1  /*Package overflow offers overflow-checked integer arithmetic operations
     2  for int, int32, and int64. Each of the operations returns a
     3  result,bool combination.  This was prompted by the need to know when
     4  to flow into higher precision types from the math.big library.
     5  
     6  For instance, assuing a 64 bit machine:
     7  
     8  10 + 20 -> 30
     9  int(math.MaxInt64) + 1 -> -9223372036854775808
    10  
    11  whereas
    12  
    13  overflow.Add(10,20) -> (30, true)
    14  overflow.Add(math.MaxInt64,1) -> (0, false)
    15  
    16  Add, Sub, Mul, Div are for int.  Add64, Add32, etc. are specifically sized.
    17  
    18  If anybody wishes an unsigned version, submit a pull request for code
    19  and new tests. */
    20  package overflow
    21  
    22  //go:generate ./overflow_template.sh
    23  
    24  import "math"
    25  
    26  func _is64Bit() bool {
    27  	maxU32 := uint(math.MaxUint32)
    28  	return ((maxU32 << 1) >> 1) == maxU32
    29  }
    30  
    31  /********** PARTIAL TEST COVERAGE FROM HERE DOWN *************
    32  
    33  The only way that I could see to do this is a combination of
    34  my normal 64 bit system and a GopherJS running on Node.  My
    35  understanding is that its ints are 32 bit.
    36  
    37  So, FEEL FREE to carefully review the code visually.
    38  
    39  *************************************************************/
    40  
    41  // Unspecified size, i.e. normal signed int
    42  
    43  // Add sums two ints, returning the result and a boolean status.
    44  func Add(a, b int) (int, bool) {
    45  	if _is64Bit() {
    46  		r64, ok := Add64(int64(a), int64(b))
    47  		return int(r64), ok
    48  	}
    49  	r32, ok := Add32(int32(a), int32(b))
    50  	return int(r32), ok
    51  }
    52  
    53  // Sub returns the difference of two ints and a boolean status.
    54  func Sub(a, b int) (int, bool) {
    55  	if _is64Bit() {
    56  		r64, ok := Sub64(int64(a), int64(b))
    57  		return int(r64), ok
    58  	}
    59  	r32, ok := Sub32(int32(a), int32(b))
    60  	return int(r32), ok
    61  }
    62  
    63  // Mul returns the product of two ints and a boolean status.
    64  func Mul(a, b int) (int, bool) {
    65  	if _is64Bit() {
    66  		r64, ok := Mul64(int64(a), int64(b))
    67  		return int(r64), ok
    68  	}
    69  	r32, ok := Mul32(int32(a), int32(b))
    70  	return int(r32), ok
    71  }
    72  
    73  // Div returns the quotient of two ints and a boolean status
    74  func Div(a, b int) (int, bool) {
    75  	if _is64Bit() {
    76  		r64, ok := Div64(int64(a), int64(b))
    77  		return int(r64), ok
    78  	}
    79  	r32, ok := Div32(int32(a), int32(b))
    80  	return int(r32), ok
    81  }
    82  
    83  // Quotient returns the quotient, remainder and status of two ints
    84  func Quotient(a, b int) (int, int, bool) {
    85  	if _is64Bit() {
    86  		q64, r64, ok := Quotient64(int64(a), int64(b))
    87  		return int(q64), int(r64), ok
    88  	}
    89  	q32, r32, ok := Quotient32(int32(a), int32(b))
    90  	return int(q32), int(r32), ok
    91  }
    92  
    93  /************* Panic versions for int ****************/
    94  
    95  // Addp returns the sum of two ints, panicking on overflow
    96  func Addp(a, b int) int {
    97  	r, ok := Add(a, b)
    98  	if !ok {
    99  		panic("addition overflow")
   100  	}
   101  	return r
   102  }
   103  
   104  // Subp returns the difference of two ints, panicking on overflow.
   105  func Subp(a, b int) int {
   106  	r, ok := Sub(a, b)
   107  	if !ok {
   108  		panic("subtraction overflow")
   109  	}
   110  	return r
   111  }
   112  
   113  // Mulp returns the product of two ints, panicking on overflow.
   114  func Mulp(a, b int) int {
   115  	r, ok := Mul(a, b)
   116  	if !ok {
   117  		panic("multiplication overflow")
   118  	}
   119  	return r
   120  }
   121  
   122  // Divp returns the quotient of two ints, panicking on overflow.
   123  func Divp(a, b int) int {
   124  	r, ok := Div(a, b)
   125  	if !ok {
   126  		panic("division failure")
   127  	}
   128  	return r
   129  }