1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- package goja
- // inspired by https://gist.github.com/orlp/3551590
- var overflows = [64]int64{
- 9223372036854775807, 9223372036854775807, 3037000499, 2097151,
- 55108, 6208, 1448, 511,
- 234, 127, 78, 52,
- 38, 28, 22, 18,
- 15, 13, 11, 9,
- 8, 7, 7, 6,
- 6, 5, 5, 5,
- 4, 4, 4, 4,
- 3, 3, 3, 3,
- 3, 3, 3, 3,
- 2, 2, 2, 2,
- 2, 2, 2, 2,
- 2, 2, 2, 2,
- 2, 2, 2, 2,
- 2, 2, 2, 2,
- 2, 2, 2, 2,
- }
- var highestBitSet = [63]byte{
- 0, 1, 2, 2, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6,
- }
- func ipow(base, exp int64) (result int64) {
- if exp >= 63 {
- if base == 1 {
- return 1
- }
- if base == -1 {
- return 1 - 2*(exp&1)
- }
- return 0
- }
- if base > overflows[exp] || -base > overflows[exp] {
- return 0
- }
- result = 1
- switch highestBitSet[byte(exp)] {
- case 6:
- if exp&1 != 0 {
- result *= base
- }
- exp >>= 1
- base *= base
- fallthrough
- case 5:
- if exp&1 != 0 {
- result *= base
- }
- exp >>= 1
- base *= base
- fallthrough
- case 4:
- if exp&1 != 0 {
- result *= base
- }
- exp >>= 1
- base *= base
- fallthrough
- case 3:
- if exp&1 != 0 {
- result *= base
- }
- exp >>= 1
- base *= base
- fallthrough
- case 2:
- if exp&1 != 0 {
- result *= base
- }
- exp >>= 1
- base *= base
- fallthrough
- case 1:
- if exp&1 != 0 {
- result *= base
- }
- fallthrough
- default:
- return result
- }
- }
|