github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/ipow.go (about) 1 package goja 2 3 // inspired by https://gist.github.com/orlp/3551590 4 5 var overflows = [64]int64{ 6 9223372036854775807, 9223372036854775807, 3037000499, 2097151, 7 55108, 6208, 1448, 511, 8 234, 127, 78, 52, 9 38, 28, 22, 18, 10 15, 13, 11, 9, 11 8, 7, 7, 6, 12 6, 5, 5, 5, 13 4, 4, 4, 4, 14 3, 3, 3, 3, 15 3, 3, 3, 3, 16 2, 2, 2, 2, 17 2, 2, 2, 2, 18 2, 2, 2, 2, 19 2, 2, 2, 2, 20 2, 2, 2, 2, 21 2, 2, 2, 2, 22 } 23 24 var highestBitSet = [63]byte{ 25 0, 1, 2, 2, 3, 3, 3, 3, 26 4, 4, 4, 4, 4, 4, 4, 4, 27 5, 5, 5, 5, 5, 5, 5, 5, 28 5, 5, 5, 5, 5, 5, 5, 5, 29 6, 6, 6, 6, 6, 6, 6, 6, 30 6, 6, 6, 6, 6, 6, 6, 6, 31 6, 6, 6, 6, 6, 6, 6, 6, 32 6, 6, 6, 6, 6, 6, 6, 33 } 34 35 func ipow(base, exp int64) (result int64) { 36 if exp >= 63 { 37 if base == 1 { 38 return 1 39 } 40 41 if base == -1 { 42 return 1 - 2*(exp&1) 43 } 44 45 return 0 46 } 47 48 if base > overflows[exp] || -base > overflows[exp] { 49 return 0 50 } 51 52 result = 1 53 54 switch highestBitSet[byte(exp)] { 55 case 6: 56 if exp&1 != 0 { 57 result *= base 58 } 59 exp >>= 1 60 base *= base 61 fallthrough 62 case 5: 63 if exp&1 != 0 { 64 result *= base 65 } 66 exp >>= 1 67 base *= base 68 fallthrough 69 case 4: 70 if exp&1 != 0 { 71 result *= base 72 } 73 exp >>= 1 74 base *= base 75 fallthrough 76 case 3: 77 if exp&1 != 0 { 78 result *= base 79 } 80 exp >>= 1 81 base *= base 82 fallthrough 83 case 2: 84 if exp&1 != 0 { 85 result *= base 86 } 87 exp >>= 1 88 base *= base 89 fallthrough 90 case 1: 91 if exp&1 != 0 { 92 result *= base 93 } 94 fallthrough 95 default: 96 return result 97 } 98 }