fork(1) download
  1. // Exponentiation operator. (2.00)
  2.  
  3. import Foundation
  4.  
  5. precedencegroup ExponentiationPrecedence {
  6. associativity: right
  7. higherThan: MultiplicationPrecedence
  8. }
  9.  
  10. infix operator ** : ExponentiationPrecedence
  11.  
  12. func ** <T: BinaryFloatingPoint>(_ x: T, _ y: T) -> Double {
  13. return pow(Double(x), Double(y))
  14. }
  15.  
  16. func ** <T: BinaryInteger>(_ x: T, _ y: T) -> Int {
  17. let base = Int(x)
  18. let expt = Int(y)
  19.  
  20. if base == 0 || base == 1 {
  21. return base
  22. }
  23. if base == -1 {
  24. return expt % 2 == 0 ? 1 : -1
  25. }
  26. if expt < 0 {
  27. return 0
  28. }
  29.  
  30. func detail(_ base: Int, _ expt: Int) -> Int {
  31. switch expt {
  32. case 0:
  33. return 1
  34. case 1:
  35. return base
  36. case _ where expt % 2 == 0:
  37. return detail(base * base, expt / 2)
  38. default:
  39. return base * detail(base, expt - 1)
  40. }
  41. }
  42.  
  43. return detail(base, expt)
  44. }
  45.  
  46. // Test.
  47.  
  48. func check<T: Equatable>(_ f: () -> Any, expect: T) {
  49. let result = f()
  50. print(result, terminator: "\t")
  51. if let x = result as? T {
  52. print(x == expect ? "Pass." : "Fail: \(expect)")
  53. } else {
  54. print("Fail: \(type(of: result)) not \(T.self)")
  55. }
  56. }
  57.  
  58. #if DEBUG
  59. check({2 ** 0}, expect: 2)
  60. check({2 ** Int8(1)}, expect: 2.0)
  61. check({2.0 ** 2}, expect: 4)
  62. #endif
  63.  
  64. check({0 ** 0}, expect: 0)
  65. check({0 ** 1}, expect: 0)
  66. check({1 ** 0}, expect: 1)
  67. check({1 ** 1}, expect: 1)
  68. check({1 ** -1}, expect: 1)
  69. check({1 ** -2}, expect: 1)
  70.  
  71. check({-1 ** 0}, expect: 1)
  72. check({-1 ** 1}, expect: -1)
  73. check({-1 ** 2}, expect: 1)
  74. check({-1 ** -1}, expect: -1)
  75. check({-1 ** -2}, expect: 1)
  76.  
  77. check({-2 ** 0}, expect: 1)
  78. check({-2 ** 1}, expect: -2)
  79. check({-2 ** 2}, expect: 4)
  80. check({-2 ** -1}, expect: 0)
  81. check({-2 ** -2}, expect: 0)
  82.  
  83. check({2 ** 0}, expect: 1)
  84. check({2 ** Int8(1)}, expect: 2)
  85. check({2.0 ** 2}, expect: 4.0)
  86. check({2.0 ** Float(3)}, expect: 8.0)
  87. check({2 ** 4.0}, expect: 16.0)
  88. check({2.0 ** 5.0}, expect: 32.0)
  89. check({2 * 2 ** 4 * 2}, expect: 64)
Success #stdin #stdout 0.02s 21224KB
stdin
Standard input is empty
stdout
0	Pass.
0	Pass.
1	Pass.
1	Pass.
1	Pass.
1	Pass.
1	Pass.
-1	Pass.
1	Pass.
-1	Pass.
1	Pass.
1	Pass.
-2	Pass.
4	Pass.
0	Pass.
0	Pass.
1	Pass.
2	Pass.
4.0	Pass.
8.0	Pass.
16.0	Pass.
32.0	Pass.
64	Pass.