1. # for our tantrums
  2. my class X::Numeric::DivideByZero { ... }
  3. my role Numeric {
  4. multi method Numeric(Numeric:D:) { self }
  5. multi method ACCEPTS(Numeric:D: Any:D \a) {
  6. with a.Numeric { self.isNaN && .isNaN or $_ == self } else { False }
  7. }
  8. proto method log(|) {*}
  9. multi method log(Numeric:D: Cool $base) { self.log / $base.Numeric.log }
  10. multi method log(Numeric:D: Numeric $base) { self.log / $base.log }
  11. method log10() { self.log / 10e0.log }
  12. proto method exp(|) {*}
  13. multi method exp(Numeric:D: $base) {
  14. $base ** self;
  15. }
  16. method roots(Cool $n) { self.Complex.roots($n.Int) }
  17. method FatRat(Numeric:D:) { self.Rat.FatRat }
  18. multi method Bool(Numeric:D:) { self != 0 }
  19. multi method gist(Numeric:D:) { self.Str }
  20. multi method DUMP(Numeric:D:) { self.perl }
  21. method succ() { self + 1 }
  22. method pred() { self - 1 }
  23. }
  24. multi sub infix:<eqv>(Numeric:D \a, Numeric:D \b) {
  25. nqp::p6bool( # RT #127951
  26. nqp::eqaddr(a,b) || (
  27. nqp::eqaddr(a.WHAT,b.WHAT)
  28. && nqp::if(nqp::istype(a, Num), (a === b), (a == b))
  29. )) # for Nums use === to properly handle signed zeros and NaNs
  30. }
  31. ## arithmetic operators
  32. proto sub prefix:<+>($?) is pure { * }
  33. multi sub prefix:<+>(\a) { a.Numeric }
  34. proto sub prefix:<->($?) is pure { * }
  35. multi sub prefix:<->(\a) { -a.Numeric }
  36. proto sub abs($) is pure { * }
  37. multi sub abs(\a) { abs a.Numeric }
  38. proto sub sign($) is pure {*}
  39. multi sub sign(Numeric \x) { x.sign }
  40. multi sub sign(Cool \x) { x.Numeric.sign }
  41. proto sub log($, $?) is pure {*}
  42. multi sub log(Numeric $x) { $x.log }
  43. multi sub log(Numeric $x, Numeric $base) { $x.log($base) }
  44. multi sub log(Cool $x) { $x.Numeric.log }
  45. multi sub log(Cool $x, Cool $base) { $x.Numeric.log($base.Numeric) }
  46. proto sub log10($, $?) is pure {*}
  47. multi sub log10(Numeric $x) { $x.log(10e0) }
  48. multi sub log10(Cool $x) { $x.Numeric.log(10e0) }
  49. proto sub exp($, $?) is pure {*}
  50. multi sub exp(Numeric $x) { $x.exp }
  51. multi sub exp(Numeric $x, Numeric $base) { $x.exp($base) }
  52. proto sub sin($) is pure {*}
  53. multi sub sin(Numeric \x) { x.sin }
  54. multi sub sin(Cool \x) { x.Numeric.sin }
  55. proto sub asin($) is pure {*}
  56. multi sub asin(Numeric \x) { x.asin }
  57. multi sub asin(Cool \x) { x.Numeric.asin }
  58. proto sub cos($) is pure {*}
  59. multi sub cos(Numeric \x) { x.cos }
  60. multi sub cos(Cool \x) { x.Numeric.cos }
  61. proto sub acos($) is pure {*}
  62. multi sub acos(Numeric \x) { x.acos }
  63. multi sub acos(Cool \x) { x.Numeric.acos }
  64. proto sub tan($) is pure {*}
  65. multi sub tan(Numeric \x) { x.tan }
  66. multi sub tan(Cool \x) { x.Numeric.tan }
  67. proto sub atan($) is pure {*}
  68. multi sub atan(Numeric \x) { x.atan }
  69. multi sub atan(Cool \x) { x.Numeric.atan }
  70. proto sub sec($) is pure {*}
  71. multi sub sec(Numeric \x) { x.sec }
  72. multi sub sec(Cool \x) { x.Numeric.sec }
  73. proto sub asec($) is pure {*}
  74. multi sub asec(Numeric \x) { x.asec }
  75. multi sub asec(Cool \x) { x.Numeric.asec }
  76. proto sub cosec($) is pure {*}
  77. multi sub cosec(Numeric \x) { x.cosec }
  78. multi sub cosec(Cool \x) { x.Numeric.cosec }
  79. proto sub acosec(|) is pure {*}
  80. multi sub acosec(Numeric \x) { x.acosec }
  81. multi sub acosec(Cool \x) { x.Numeric.acosec }
  82. proto sub cotan($) is pure {*}
  83. multi sub cotan(Numeric \x) { x.cotan }
  84. multi sub cotan(Cool \x) { x.Numeric.cotan }
  85. proto sub acotan($) is pure {*}
  86. multi sub acotan(Numeric \x) { x.acotan }
  87. multi sub acotan(Cool \x) { x.Numeric.acotan }
  88. proto sub sinh($) is pure {*}
  89. multi sub sinh(Numeric \x) { x.sinh }
  90. multi sub sinh(Cool \x) { x.Numeric.sinh }
  91. proto sub asinh($) is pure {*}
  92. multi sub asinh(Numeric \x) { x.asinh }
  93. multi sub asinh(Cool \x) { x.Numeric.asinh }
  94. proto sub cosh($) is pure {*}
  95. multi sub cosh(Numeric \x) { x.cosh }
  96. multi sub cosh(Cool \x) { x.Numeric.cosh }
  97. proto sub acosh($) is pure {*}
  98. multi sub acosh(Numeric \x) { x.acosh }
  99. multi sub acosh(Cool \x) { x.Numeric.acosh }
  100. proto sub tanh($) is pure {*}
  101. multi sub tanh(Numeric \x) { x.tanh }
  102. multi sub tanh(Cool \x) { x.Numeric.tanh }
  103. proto sub atanh($) is pure {*}
  104. multi sub atanh(Numeric \x) { x.atanh }
  105. multi sub atanh(Cool \x) { x.Numeric.atanh }
  106. proto sub sech($) is pure {*}
  107. multi sub sech(Numeric \x) { x.sech }
  108. multi sub sech(Cool \x) { x.Numeric.sech }
  109. proto sub asech($) is pure {*}
  110. multi sub asech(Numeric \x) { x.asech }
  111. multi sub asech(Cool \x) { x.Numeric.asech }
  112. proto sub cosech($) is pure {*}
  113. multi sub cosech(Numeric \x) { x.cosech }
  114. multi sub cosech(Cool \x) { x.Numeric.cosech }
  115. proto sub acosech($) is pure {*}
  116. multi sub acosech(Numeric \x) { x.acosech }
  117. multi sub acosech(Cool \x) { x.Numeric.acosech }
  118. proto sub cotanh($) is pure {*}
  119. multi sub cotanh(Numeric \x) { x.cotanh }
  120. multi sub cotanh(Cool \x) { x.Numeric.cotanh }
  121. proto sub acotanh($) is pure {*}
  122. multi sub acotanh(Numeric \x) { x.acotanh }
  123. multi sub acotanh(Cool \x) { x.Numeric.acotanh }
  124. proto sub sqrt($) is pure {*}
  125. multi sub sqrt(Numeric \x) { x.sqrt }
  126. multi sub sqrt(Cool \x) { x.Numeric.sqrt }
  127. proto sub roots($, $) is pure { * }
  128. multi sub roots($x, Cool $n) { $x.Numeric.Complex.roots($n.Int) }
  129. multi sub roots($x, Numeric $n) { $x.Numeric.Complex.roots($n.Int) }
  130. proto sub floor($) is pure { * }
  131. multi sub floor($a) { $a.Numeric.floor }
  132. multi sub floor(Numeric $a) { $a.floor }
  133. proto sub ceiling($) is pure { * }
  134. multi sub ceiling($a) { $a.Numeric.ceiling }
  135. multi sub ceiling(Numeric $a) { $a.ceiling }
  136. proto sub round($, $?) is pure { * }
  137. multi sub round($a) { $a.Numeric.round }
  138. multi sub round(Numeric $a) { $a.round }
  139. multi sub round(Numeric $a, $scale) { $a.round($scale) }
  140. proto sub infix:<+>(Mu $?, Mu $?) is pure { * }
  141. multi sub infix:<+>($x = 0) { $x.Numeric }
  142. multi sub infix:<+>(\a, \b) { a.Numeric + b.Numeric }
  143. proto sub infix:<->(Mu $?, Mu $?) is pure { * }
  144. multi sub infix:<->($x = 0) { -$x.Numeric }
  145. multi sub infix:<->(\a, \b) { a.Numeric - b.Numeric }
  146. proto sub infix:<*>(Mu $?, Mu $?) is pure { * }
  147. multi sub infix:<*>($x = 1) { $x.Numeric }
  148. multi sub infix:<*>(\a, \b) { a.Numeric * b.Numeric }
  149. sub infix:<×>(|c) is pure { infix:<*>(|c) }
  150. proto sub infix:</>(Mu $?, Mu $?) is pure { * }
  151. multi sub infix:</>() { Failure.new("No zero-arg meaning for infix:</>") }
  152. multi sub infix:</>($x) { $x.Numeric }
  153. multi sub infix:</>(\a, \b) { a.Numeric / b.Numeric }
  154. sub infix:<÷>(|c) is pure { infix:</>(|c) }
  155. proto sub infix:<div>(Mu $?, Mu $?) is pure { * }
  156. # rest of infix:<div> is in Int.pm
  157. proto sub infix:<%>(Mu $?, Mu $?) is pure { * }
  158. multi sub infix:<%>() { Failure.new("No zero-arg meaning for infix:<%>") }
  159. multi sub infix:<%>($x) { $x }
  160. multi sub infix:<%>(\a, \b) { a.Real % b.Real }
  161. proto sub infix:<%%>(Mu $?, Mu $?) is pure { * }
  162. multi sub infix:<%%>() { Failure.new("No zero-arg meaning for infix:<%%>") }
  163. multi sub infix:<%%>($) { Bool::True }
  164. multi sub infix:<%%>(Int:D \a, Int:D \b) {
  165. nqp::if(
  166. nqp::isbig_I(nqp::decont(a)) || nqp::isbig_I(nqp::decont(b)),
  167. nqp::if(
  168. b,
  169. nqp::p6bool(nqp::not_i(nqp::mod_I(nqp::decont(a),nqp::decont(b),Int))),
  170. Failure.new(
  171. X::Numeric::DivideByZero.new(using => 'infix:<%%>', numerator => a)
  172. )
  173. ),
  174. nqp::if(
  175. nqp::isne_i(b,0),
  176. nqp::p6bool(nqp::not_i(nqp::mod_i(nqp::decont(a),nqp::decont(b)))),
  177. Failure.new(
  178. X::Numeric::DivideByZero.new(using => 'infix:<%%>', numerator => a)
  179. )
  180. )
  181. )
  182. }
  183. multi sub infix:<%%>(\a, \b) {
  184. nqp::if(
  185. b,
  186. (a.Real % b.Real == 0),
  187. Failure.new(
  188. X::Numeric::DivideByZero.new(using => 'infix:<%%>', numerator => a)
  189. )
  190. )
  191. }
  192. proto sub infix:<lcm>(Mu $?, Mu $?) is pure { * }
  193. multi sub infix:<lcm>(Int $x = 1) { $x }
  194. multi sub infix:<lcm>(\a, \b) { a.Int lcm b.Int }
  195. proto sub infix:<gcd>(Mu $?, Mu $?) is pure { * }
  196. multi sub infix:<gcd>() { Failure.new('No zero-arg meaning for infix:<gcd>') }
  197. multi sub infix:<gcd>(Int $x) { $x }
  198. multi sub infix:<gcd>(\a, \b) { a.Int gcd b.Int }
  199. proto sub infix:<**>(Mu $?, Mu $?) is pure { * }
  200. multi sub infix:<**>($x = 1) { $x.Numeric }
  201. multi sub infix:<**>(\a, \b) { a.Numeric ** b.Numeric }
  202. proto sub postfix:<ⁿ>(Mu $, Mu $) is pure { * }
  203. multi sub postfix:<ⁿ>(\a, \b) { a ** b }
  204. ## relational operators
  205. proto sub infix:«<=>»(Mu $, Mu $?) is pure { * }
  206. multi sub infix:«<=>»(\a, \b) { a.Real <=> b.Real }
  207. proto sub infix:<==>(Mu $?, Mu $?) is pure { * }
  208. multi sub infix:<==>($?) { Bool::True }
  209. multi sub infix:<==>(\a, \b) { a.Numeric == b.Numeric }
  210. proto sub infix:<≅>(Mu $?, Mu $?, *%) { * } # note, can't be pure due to dynvar
  211. multi sub infix:<≅>($?) { Bool::True }
  212. multi sub infix:<≅>(\a, \b, :$tolerance = $*TOLERANCE) {
  213. # If operands are non-0, scale the tolerance to the larger of the abs values.
  214. # We test b first since $value ≅ 0 is the usual idiom and falsifies faster.
  215. if b && a && $tolerance {
  216. abs(a - b) < (a.abs max b.abs) * $tolerance;
  217. }
  218. else { # interpret tolerance as absolute
  219. abs(a.Num - b.Num) < $tolerance;
  220. }
  221. }
  222. sub infix:<=~=>(|c) { infix:<≅>(|c) }
  223. proto sub infix:<!=>(Mu $?, Mu $?) is pure { * }
  224. multi sub infix:<!=>($?) { Bool::True }
  225. multi sub infix:<!=>(Mu \a, Mu \b) { not a == b }
  226. sub infix:<≠>(|c) is pure { infix:<!=>(|c) }
  227. proto sub infix:«<»(Mu $?, Mu $?) is pure { * }
  228. multi sub infix:«<»($?) { Bool::True }
  229. multi sub infix:«<»(\a, \b) { a.Real < b.Real }
  230. proto sub infix:«<=»(Mu $?, Mu $?) is pure { * }
  231. multi sub infix:«<=»($?) { Bool::True }
  232. multi sub infix:«<=»(\a, \b) { a.Real <= b.Real }
  233. sub infix:«≤»(|c) is pure { infix:«<=»(|c) }
  234. proto sub infix:«>»(Mu $?, Mu $?) is pure { * }
  235. multi sub infix:«>»($?) { Bool::True }
  236. multi sub infix:«>»(\a, \b) { a.Real > b.Real }
  237. proto sub infix:«>=»(Mu $?, Mu $?) is pure { * }
  238. multi sub infix:«>=»($?) { Bool::True }
  239. multi sub infix:«>=»(\a, \b) { a.Real >= b.Real }
  240. sub infix:«≥»(|c) is pure { infix:«>=»(|c) }
  241. ## bitwise operators
  242. proto sub infix:<+&>(Mu $?, Mu $?) is pure { * }
  243. multi sub infix:<+&>() { +^0 }
  244. multi sub infix:<+&>($x) { $x }
  245. multi sub infix:<+&>($x, $y) { $x.Numeric.Int +& $y.Numeric.Int }
  246. proto sub infix:<+|>(Mu $?, Mu $?) is pure { * }
  247. multi sub infix:<+|>() { 0 }
  248. multi sub infix:<+|>($x) { $x }
  249. multi sub infix:<+|>($x, $y) { $x.Numeric.Int +| $y.Numeric.Int }
  250. proto sub infix:<+^>(Mu $?, Mu $?) is pure { * }
  251. multi sub infix:<+^>() { 0 }
  252. multi sub infix:<+^>($x) { $x }
  253. multi sub infix:<+^>($x, $y) { $x.Numeric.Int +^ $y.Numeric.Int }
  254. proto sub infix:«+<»(Mu $?, Mu $?) is pure { * }
  255. multi sub infix:«+<»() { Failure.new("No zero-arg meaning for infix:«+<»") }
  256. multi sub infix:«+<»($x) { $x }
  257. multi sub infix:«+<»($x,$y) { $x.Numeric.Int +< $y.Numeric.Int }
  258. proto sub infix:«+>»(Mu $?, Mu $?) is pure { * }
  259. multi sub infix:«+>»() { Failure.new("No zero-arg meaning for infix:«+>»") }
  260. multi sub infix:«+>»($x) { $x }
  261. multi sub infix:«+>»($x,$y) { $x.Numeric.Int +> $y.Numeric.Int }
  262. proto sub prefix:<+^>(Mu $) is pure { * }
  263. multi sub prefix:<+^>($x) { +^ $x.Numeric.Int }