fork download
  1. // Exponentiation operator. (2.02)
  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 expt == 0 {
  21. return 1
  22. } else if base == 0 || base == 1 {
  23. return base
  24. } else if base == -1 {
  25. return expt % 2 == 0 ? 1 : -1
  26. } else if expt < 0 {
  27. return 0
  28. }
  29.  
  30. func detail(_ base: Int, _ expt: Int) -> Int {
  31. if expt == 1 {
  32. return base
  33. } else if expt % 2 == 0 {
  34. return detail(base * base, expt / 2)
  35. } else {
  36. return base * detail(base, expt - 1)
  37. }
  38. }
  39.  
  40. return detail(base, expt)
  41. }
  42.  
  43. // Test.
  44.  
  45. func check<T: Equatable>(_ f: () -> Any, expect: T) {
  46. let result = f()
  47. print(result, terminator: "\t")
  48. if let x = result as? T {
  49. print(x == expect ? "Pass." : "Fail: \(expect)")
  50. } else {
  51. print("Fail: \(type(of: result)) not \(T.self)")
  52. }
  53. }
  54.  
  55. #if DEBUG
  56. check({2 ** 0}, expect: 2)
  57. check({2 ** Int8(1)}, expect: 2.0)
  58. check({2.0 ** 2}, expect: 4)
  59. #endif
  60.  
  61. // Zero.
  62.  
  63. check({0 ** -2}, expect: 0)
  64. check({0 ** -1}, expect: 0)
  65. check({0 ** 0}, expect: 1)
  66. check({0 ** 1}, expect: 0)
  67. check({0 ** 2}, expect: 0)
  68.  
  69. // Positive.
  70.  
  71. check({1 ** -2}, expect: 1)
  72. check({1 ** -1}, expect: 1)
  73. check({1 ** 0}, expect: 1)
  74. check({1 ** 1}, expect: 1)
  75. check({1 ** 2}, expect: 1)
  76.  
  77. check({2 ** -2}, expect: 0)
  78. check({2 ** -1}, expect: 0)
  79. check({2 ** 0}, expect: 1)
  80. check({2 ** 1}, expect: 2)
  81. check({2 ** 2}, expect: 4)
  82.  
  83. // Negative.
  84.  
  85. check({-1 ** -2}, expect: 1)
  86. check({-1 ** -1}, expect: -1)
  87. check({-1 ** 0}, expect: 1)
  88. check({-1 ** 1}, expect: -1)
  89. check({-1 ** 2}, expect: 1)
  90.  
  91. check({-2 ** -2}, expect: 0)
  92. check({-2 ** -1}, expect: 0)
  93. check({-2 ** 0}, expect: 1)
  94. check({-2 ** 1}, expect: -2)
  95. check({-2 ** 2}, expect: 4)
  96.  
  97. // Floating point and mixed types.
  98.  
  99. check({2 ** Int8(1)}, expect: 2)
  100. check({2.0 ** 2}, expect: 4.0)
  101. check({2.0 ** Float(3)}, expect: 8.0)
  102. check({2 ** 4.0}, expect: 16.0)
  103. check({2.0 ** 5.0}, expect: 32.0)
  104.  
  105. // Precedence and associativity.
  106.  
  107. check({3 * 2 ** 2}, expect: 12)
  108. check({2 ** 2 ** 3}, expect: 256)
  109. check({2 ** 3 ** 2}, expect: 512)
Success #stdin #stdout 0.02s 21292KB
stdin
Standard input is empty
stdout
0	Pass.
0	Pass.
1	Pass.
0	Pass.
0	Pass.
1	Pass.
1	Pass.
1	Pass.
1	Pass.
1	Pass.
0	Pass.
0	Pass.
1	Pass.
2	Pass.
4	Pass.
1	Pass.
-1	Pass.
1	Pass.
-1	Pass.
1	Pass.
0	Pass.
0	Pass.
1	Pass.
-2	Pass.
4	Pass.
2	Pass.
4.0	Pass.
8.0	Pass.
16.0	Pass.
32.0	Pass.
12	Pass.
256	Pass.
512	Pass.