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