github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/runtime/numeric.go (about)

     1  package grumpy
     2  
     3  import (
     4  	"math/big"
     5  	"strings"
     6  )
     7  
     8  const (
     9  	// Here we calculate the number of bits in a uint and use that to
    10  	// create a typeless constant _maxuint which is the largest value that
    11  	// can be held by a uint. We then use that to create the constants
    12  	// MaxInt and MinInt below.
    13  	// Because these constants are typeless, they can be used wherever
    14  	// a numeric value is needed, without a conversion like int64().
    15  	// A typeless number remains untyped when shifted, even if the shift
    16  	// count is typed.
    17  	// Start with the two's complement of 0 as a uint which is 0xffff...ff.
    18  	// This is the number we are after, but it currently has a type (uint).
    19  	// Dividing it by 0xff gives us 0x0101...01 for the length of a uint.
    20  	// Taking that mod 15 is effectively counting the ones - one for each
    21  	// byte in a uint, so we have either 4 or 8.
    22  	// We multiply by 8 and shift, and now we have 2^32 or 2^64 as a
    23  	// typeless constant number.
    24  	// We subtract 1 from that to get maxuint.
    25  	_maxuint = 1<<(^uint(0)/0xff%15*8) - 1
    26  
    27  	// MaxInt is the largest (most positive) number that can be stored as an int.
    28  	MaxInt = _maxuint >> 1
    29  	// MinInt is the smallest (most negative) number that can be stored as an int.
    30  	// The absolute value of MinInt is Maxint+1, thus it can be tricky to deal with.
    31  	MinInt = -(_maxuint + 1) >> 1
    32  )
    33  
    34  var (
    35  	maxIntBig = big.NewInt(MaxInt)
    36  	minIntBig = big.NewInt(MinInt)
    37  )
    38  
    39  func numParseInteger(z *big.Int, s string, base int) (*big.Int, bool) {
    40  	s = strings.TrimSpace(s)
    41  	if len(s) > 2 && s[0] == '0' {
    42  		switch s[1] {
    43  		case 'b', 'B':
    44  			if base == 0 || base == 2 {
    45  				base = 2
    46  				s = s[2:]
    47  			}
    48  		case 'o', 'O':
    49  			if base == 0 || base == 8 {
    50  				base = 8
    51  				s = s[2:]
    52  			}
    53  		case 'x', 'X':
    54  			if base == 0 || base == 16 {
    55  				base = 16
    56  				s = s[2:]
    57  			}
    58  		default:
    59  			base = 8
    60  		}
    61  	}
    62  	if base == 0 {
    63  		base = 10
    64  	}
    65  	return z.SetString(s, base)
    66  }
    67  
    68  func numInIntRange(i *big.Int) bool {
    69  	return i.Cmp(minIntBig) >= 0 && i.Cmp(maxIntBig) <= 0
    70  }