ipow.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package goja
  2. // ported from https://gist.github.com/orlp/3551590
  3. var highest_bit_set = [256]byte{
  4. 0, 1, 2, 2, 3, 3, 3, 3,
  5. 4, 4, 4, 4, 4, 4, 4, 4,
  6. 5, 5, 5, 5, 5, 5, 5, 5,
  7. 5, 5, 5, 5, 5, 5, 5, 5,
  8. 6, 6, 6, 6, 6, 6, 6, 6,
  9. 6, 6, 6, 6, 6, 6, 6, 6,
  10. 6, 6, 6, 6, 6, 6, 6, 6,
  11. 6, 6, 6, 6, 6, 6, 6, 255, // anything past 63 is a guaranteed overflow with base > 1
  12. 255, 255, 255, 255, 255, 255, 255, 255,
  13. 255, 255, 255, 255, 255, 255, 255, 255,
  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. }
  37. func ipow(base, exp int64) (result int64) {
  38. result = 1
  39. switch highest_bit_set[byte(exp)] {
  40. case 255: // we use 255 as an overflow marker and return 0 on overflow/underflow
  41. if base == 1 {
  42. return 1
  43. }
  44. if base == -1 {
  45. return 1 - 2*(exp&1)
  46. }
  47. return 0
  48. case 6:
  49. if exp&1 != 0 {
  50. result *= base
  51. }
  52. exp >>= 1
  53. base *= base
  54. fallthrough
  55. case 5:
  56. if exp&1 != 0 {
  57. result *= base
  58. }
  59. exp >>= 1
  60. base *= base
  61. fallthrough
  62. case 4:
  63. if exp&1 != 0 {
  64. result *= base
  65. }
  66. exp >>= 1
  67. base *= base
  68. fallthrough
  69. case 3:
  70. if exp&1 != 0 {
  71. result *= base
  72. }
  73. exp >>= 1
  74. base *= base
  75. fallthrough
  76. case 2:
  77. if exp&1 != 0 {
  78. result *= base
  79. }
  80. exp >>= 1
  81. base *= base
  82. fallthrough
  83. case 1:
  84. if exp&1 != 0 {
  85. result *= base
  86. }
  87. fallthrough
  88. default:
  89. return result
  90. }
  91. }