go.ketch.com/lib/goja@v0.0.1/ipow.go (about)

     1  package goja
     2  
     3  // ported from https://gist.github.com/orlp/3551590
     4  
     5  var highest_bit_set = [256]byte{
     6  	0, 1, 2, 2, 3, 3, 3, 3,
     7  	4, 4, 4, 4, 4, 4, 4, 4,
     8  	5, 5, 5, 5, 5, 5, 5, 5,
     9  	5, 5, 5, 5, 5, 5, 5, 5,
    10  	6, 6, 6, 6, 6, 6, 6, 6,
    11  	6, 6, 6, 6, 6, 6, 6, 6,
    12  	6, 6, 6, 6, 6, 6, 6, 6,
    13  	6, 6, 6, 6, 6, 6, 6, 255, // anything past 63 is a guaranteed overflow with base > 1
    14  	255, 255, 255, 255, 255, 255, 255, 255,
    15  	255, 255, 255, 255, 255, 255, 255, 255,
    16  	255, 255, 255, 255, 255, 255, 255, 255,
    17  	255, 255, 255, 255, 255, 255, 255, 255,
    18  	255, 255, 255, 255, 255, 255, 255, 255,
    19  	255, 255, 255, 255, 255, 255, 255, 255,
    20  	255, 255, 255, 255, 255, 255, 255, 255,
    21  	255, 255, 255, 255, 255, 255, 255, 255,
    22  	255, 255, 255, 255, 255, 255, 255, 255,
    23  	255, 255, 255, 255, 255, 255, 255, 255,
    24  	255, 255, 255, 255, 255, 255, 255, 255,
    25  	255, 255, 255, 255, 255, 255, 255, 255,
    26  	255, 255, 255, 255, 255, 255, 255, 255,
    27  	255, 255, 255, 255, 255, 255, 255, 255,
    28  	255, 255, 255, 255, 255, 255, 255, 255,
    29  	255, 255, 255, 255, 255, 255, 255, 255,
    30  	255, 255, 255, 255, 255, 255, 255, 255,
    31  	255, 255, 255, 255, 255, 255, 255, 255,
    32  	255, 255, 255, 255, 255, 255, 255, 255,
    33  	255, 255, 255, 255, 255, 255, 255, 255,
    34  	255, 255, 255, 255, 255, 255, 255, 255,
    35  	255, 255, 255, 255, 255, 255, 255, 255,
    36  	255, 255, 255, 255, 255, 255, 255, 255,
    37  	255, 255, 255, 255, 255, 255, 255, 255,
    38  }
    39  
    40  func ipow(base, exp int64) (result int64) {
    41  	result = 1
    42  
    43  	switch highest_bit_set[byte(exp)] {
    44  	case 255: // we use 255 as an overflow marker and return 0 on overflow/underflow
    45  		if base == 1 {
    46  			return 1
    47  		}
    48  
    49  		if base == -1 {
    50  			return 1 - 2*(exp&1)
    51  		}
    52  
    53  		return 0
    54  	case 6:
    55  		if exp&1 != 0 {
    56  			result *= base
    57  		}
    58  		exp >>= 1
    59  		base *= base
    60  		fallthrough
    61  	case 5:
    62  		if exp&1 != 0 {
    63  			result *= base
    64  		}
    65  		exp >>= 1
    66  		base *= base
    67  		fallthrough
    68  	case 4:
    69  		if exp&1 != 0 {
    70  			result *= base
    71  		}
    72  		exp >>= 1
    73  		base *= base
    74  		fallthrough
    75  	case 3:
    76  		if exp&1 != 0 {
    77  			result *= base
    78  		}
    79  		exp >>= 1
    80  		base *= base
    81  		fallthrough
    82  	case 2:
    83  		if exp&1 != 0 {
    84  			result *= base
    85  		}
    86  		exp >>= 1
    87  		base *= base
    88  		fallthrough
    89  	case 1:
    90  		if exp&1 != 0 {
    91  			result *= base
    92  		}
    93  		fallthrough
    94  	default:
    95  		return result
    96  	}
    97  }