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