math.nim 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## *Constructive mathematics is naturally typed.* -- Simon Thompson
  10. ##
  11. ## Basic math routines for Nim.
  12. ##
  13. ## Note that the trigonometric functions naturally operate on radians.
  14. ## The helper functions `degToRad<#degToRad,T>`_ and `radToDeg<#radToDeg,T>`_
  15. ## provide conversion between radians and degrees.
  16. ##
  17. ## .. code-block::
  18. ##
  19. ## import math
  20. ## from sequtils import map
  21. ##
  22. ## let a = [0.0, PI/6, PI/4, PI/3, PI/2]
  23. ##
  24. ## echo a.map(sin)
  25. ## # @[0.0, 0.499…, 0.707…, 0.866…, 1.0]
  26. ##
  27. ## echo a.map(tan)
  28. ## # @[0.0, 0.577…, 0.999…, 1.732…, 1.633…e+16]
  29. ##
  30. ## echo cos(degToRad(180.0))
  31. ## # -1.0
  32. ##
  33. ## echo sqrt(-1.0)
  34. ## # nan (use `complex` module)
  35. ##
  36. ## This module is available for the `JavaScript target
  37. ## <backends.html#backends-the-javascript-target>`_.
  38. ##
  39. ## **See also:**
  40. ## * `complex module<complex.html>`_ for complex numbers and their
  41. ## mathematical operations
  42. ## * `rationals module<rationals.html>`_ for rational numbers and their
  43. ## mathematical operations
  44. ## * `fenv module<fenv.html>`_ for handling of floating-point rounding
  45. ## and exceptions (overflow, zero-divide, etc.)
  46. ## * `random module<random.html>`_ for fast and tiny random number generator
  47. ## * `mersenne module<mersenne.html>`_ for Mersenne twister random number generator
  48. ## * `stats module<stats.html>`_ for statistical analysis
  49. ## * `strformat module<strformat.html>`_ for formatting floats for print
  50. ## * `system module<system.html>`_ Some very basic and trivial math operators
  51. ## are on system directly, to name a few ``shr``, ``shl``, ``xor``, ``clamp``, etc.
  52. include "system/inclrtl"
  53. {.push debugger: off.} # the user does not want to trace a part
  54. # of the standard library!
  55. import bitops
  56. proc binom*(n, k: int): int {.noSideEffect.} =
  57. ## Computes the `binomial coefficient <https://en.wikipedia.org/wiki/Binomial_coefficient>`_.
  58. runnableExamples:
  59. doAssert binom(6, 2) == binom(6, 4)
  60. doAssert binom(6, 2) == 15
  61. doAssert binom(-6, 2) == 1
  62. doAssert binom(6, 0) == 1
  63. if k <= 0: return 1
  64. if 2*k > n: return binom(n, n-k)
  65. result = n
  66. for i in countup(2, k):
  67. result = (result * (n + 1 - i)) div i
  68. proc createFactTable[N: static[int]]: array[N, int] =
  69. result[0] = 1
  70. for i in 1 ..< N:
  71. result[i] = result[i - 1] * i
  72. proc fac*(n: int): int =
  73. ## Computes the `factorial <https://en.wikipedia.org/wiki/Factorial>`_ of
  74. ## a non-negative integer ``n``.
  75. ##
  76. ## See also:
  77. ## * `prod proc <#prod,openArray[T]>`_
  78. runnableExamples:
  79. doAssert fac(3) == 6
  80. doAssert fac(4) == 24
  81. doAssert fac(10) == 3628800
  82. const factTable =
  83. when sizeof(int) == 2:
  84. createFactTable[5]()
  85. elif sizeof(int) == 4:
  86. createFactTable[13]()
  87. else:
  88. createFactTable[21]()
  89. assert(n >= 0, $n & " must not be negative.")
  90. assert(n < factTable.len, $n & " is too large to look up in the table")
  91. factTable[n]
  92. {.push checks: off, line_dir: off, stack_trace: off.}
  93. when defined(Posix) and not defined(genode):
  94. {.passl: "-lm".}
  95. const
  96. PI* = 3.1415926535897932384626433 ## The circle constant PI (Ludolph's number)
  97. TAU* = 2.0 * PI ## The circle constant TAU (= 2 * PI)
  98. E* = 2.71828182845904523536028747 ## Euler's number
  99. MaxFloat64Precision* = 16 ## Maximum number of meaningful digits
  100. ## after the decimal point for Nim's
  101. ## ``float64`` type.
  102. MaxFloat32Precision* = 8 ## Maximum number of meaningful digits
  103. ## after the decimal point for Nim's
  104. ## ``float32`` type.
  105. MaxFloatPrecision* = MaxFloat64Precision ## Maximum number of
  106. ## meaningful digits
  107. ## after the decimal point
  108. ## for Nim's ``float`` type.
  109. MinFloatNormal* = 2.225073858507201e-308 ## Smallest normal number for Nim's
  110. ## ``float`` type. (= 2^-1022).
  111. RadPerDeg = PI / 180.0 ## Number of radians per degree
  112. type
  113. FloatClass* = enum ## Describes the class a floating point value belongs to.
  114. ## This is the type that is returned by
  115. ## `classify proc <#classify,float>`_.
  116. fcNormal, ## value is an ordinary nonzero floating point value
  117. fcSubnormal, ## value is a subnormal (a very small) floating point value
  118. fcZero, ## value is zero
  119. fcNegZero, ## value is the negative zero
  120. fcNan, ## value is Not-A-Number (NAN)
  121. fcInf, ## value is positive infinity
  122. fcNegInf ## value is negative infinity
  123. proc classify*(x: float): FloatClass =
  124. ## Classifies a floating point value.
  125. ##
  126. ## Returns ``x``'s class as specified by `FloatClass enum<#FloatClass>`_.
  127. runnableExamples:
  128. doAssert classify(0.3) == fcNormal
  129. doAssert classify(0.0) == fcZero
  130. doAssert classify(0.3/0.0) == fcInf
  131. doAssert classify(-0.3/0.0) == fcNegInf
  132. doAssert classify(5.0e-324) == fcSubnormal
  133. # JavaScript and most C compilers have no classify:
  134. if x == 0.0:
  135. if 1.0/x == Inf:
  136. return fcZero
  137. else:
  138. return fcNegZero
  139. if x*0.5 == x:
  140. if x > 0.0: return fcInf
  141. else: return fcNegInf
  142. if x != x: return fcNan
  143. if abs(x) < MinFloatNormal:
  144. return fcSubnormal
  145. return fcNormal
  146. proc isPowerOfTwo*(x: int): bool {.noSideEffect.} =
  147. ## Returns ``true``, if ``x`` is a power of two, ``false`` otherwise.
  148. ##
  149. ## Zero and negative numbers are not a power of two.
  150. ##
  151. ## See also:
  152. ## * `nextPowerOfTwo proc<#nextPowerOfTwo,int>`_
  153. runnableExamples:
  154. doAssert isPowerOfTwo(16) == true
  155. doAssert isPowerOfTwo(5) == false
  156. doAssert isPowerOfTwo(0) == false
  157. doAssert isPowerOfTwo(-16) == false
  158. return (x > 0) and ((x and (x - 1)) == 0)
  159. proc nextPowerOfTwo*(x: int): int {.noSideEffect.} =
  160. ## Returns ``x`` rounded up to the nearest power of two.
  161. ##
  162. ## Zero and negative numbers get rounded up to 1.
  163. ##
  164. ## See also:
  165. ## * `isPowerOfTwo proc<#isPowerOfTwo,int>`_
  166. runnableExamples:
  167. doAssert nextPowerOfTwo(16) == 16
  168. doAssert nextPowerOfTwo(5) == 8
  169. doAssert nextPowerOfTwo(0) == 1
  170. doAssert nextPowerOfTwo(-16) == 1
  171. result = x - 1
  172. when defined(cpu64):
  173. result = result or (result shr 32)
  174. when sizeof(int) > 2:
  175. result = result or (result shr 16)
  176. when sizeof(int) > 1:
  177. result = result or (result shr 8)
  178. result = result or (result shr 4)
  179. result = result or (result shr 2)
  180. result = result or (result shr 1)
  181. result += 1 + ord(x <= 0)
  182. proc countBits32*(n: int32): int {.noSideEffect, deprecated:
  183. "Deprecated since v0.20.0; use 'bitops.countSetBits' instead".} =
  184. runnableExamples:
  185. doAssert countBits32(7) == 3
  186. doAssert countBits32(8) == 1
  187. doAssert countBits32(15) == 4
  188. doAssert countBits32(16) == 1
  189. doAssert countBits32(17) == 2
  190. bitops.countSetBits(n)
  191. proc sum*[T](x: openArray[T]): T {.noSideEffect.} =
  192. ## Computes the sum of the elements in ``x``.
  193. ##
  194. ## If ``x`` is empty, 0 is returned.
  195. ##
  196. ## See also:
  197. ## * `prod proc <#prod,openArray[T]>`_
  198. ## * `cumsum proc <#cumsum,openArray[T]>`_
  199. ## * `cumsummed proc <#cumsummed,openArray[T]>`_
  200. runnableExamples:
  201. doAssert sum([1, 2, 3, 4]) == 10
  202. doAssert sum([-1.5, 2.7, -0.1]) == 1.1
  203. for i in items(x): result = result + i
  204. proc prod*[T](x: openArray[T]): T {.noSideEffect.} =
  205. ## Computes the product of the elements in ``x``.
  206. ##
  207. ## If ``x`` is empty, 1 is returned.
  208. ##
  209. ## See also:
  210. ## * `sum proc <#sum,openArray[T]>`_
  211. ## * `fac proc <#fac,int>`_
  212. runnableExamples:
  213. doAssert prod([1, 2, 3, 4]) == 24
  214. doAssert prod([-4, 3, 5]) == -60
  215. result = 1.T
  216. for i in items(x): result = result * i
  217. proc cumsummed*[T](x: openArray[T]): seq[T] =
  218. ## Return cumulative (aka prefix) summation of ``x``.
  219. ##
  220. ## See also:
  221. ## * `sum proc <#sum,openArray[T]>`_
  222. ## * `cumsum proc <#cumsum,openArray[T]>`_ for the in-place version
  223. runnableExamples:
  224. let a = [1, 2, 3, 4]
  225. doAssert cumsummed(a) == @[1, 3, 6, 10]
  226. result.setLen(x.len)
  227. result[0] = x[0]
  228. for i in 1 ..< x.len: result[i] = result[i-1] + x[i]
  229. proc cumsum*[T](x: var openArray[T]) =
  230. ## Transforms ``x`` in-place (must be declared as `var`) into its
  231. ## cumulative (aka prefix) summation.
  232. ##
  233. ## See also:
  234. ## * `sum proc <#sum,openArray[T]>`_
  235. ## * `cumsummed proc <#cumsummed,openArray[T]>`_ for a version which
  236. ## returns cumsummed sequence
  237. runnableExamples:
  238. var a = [1, 2, 3, 4]
  239. cumsum(a)
  240. doAssert a == @[1, 3, 6, 10]
  241. for i in 1 ..< x.len: x[i] = x[i-1] + x[i]
  242. {.push noSideEffect.}
  243. when not defined(JS): # C
  244. proc sqrt*(x: float32): float32 {.importc: "sqrtf", header: "<math.h>".}
  245. proc sqrt*(x: float64): float64 {.importc: "sqrt", header: "<math.h>".}
  246. ## Computes the square root of ``x``.
  247. ##
  248. ## See also:
  249. ## * `cbrt proc <#cbrt,float64>`_ for cubic root
  250. ##
  251. ## .. code-block:: nim
  252. ## echo sqrt(4.0) ## 2.0
  253. ## echo sqrt(1.44) ## 1.2
  254. ## echo sqrt(-4.0) ## nan
  255. proc cbrt*(x: float32): float32 {.importc: "cbrtf", header: "<math.h>".}
  256. proc cbrt*(x: float64): float64 {.importc: "cbrt", header: "<math.h>".}
  257. ## Computes the cubic root of ``x``.
  258. ##
  259. ## See also:
  260. ## * `sqrt proc <#sqrt,float64>`_ for square root
  261. ##
  262. ## .. code-block:: nim
  263. ## echo cbrt(8.0) ## 2.0
  264. ## echo cbrt(2.197) ## 1.3
  265. ## echo cbrt(-27.0) ## -3.0
  266. proc ln*(x: float32): float32 {.importc: "logf", header: "<math.h>".}
  267. proc ln*(x: float64): float64 {.importc: "log", header: "<math.h>".}
  268. ## Computes the `natural logarithm <https://en.wikipedia.org/wiki/Natural_logarithm>`_
  269. ## of ``x``.
  270. ##
  271. ## See also:
  272. ## * `log proc <#log,T,T>`_
  273. ## * `log10 proc <#log10,float64>`_
  274. ## * `log2 proc <#log2,float64>`_
  275. ## * `exp proc <#exp,float64>`_
  276. ##
  277. ## .. code-block:: nim
  278. ## echo ln(exp(4.0)) ## 4.0
  279. ## echo ln(1.0)) ## 0.0
  280. ## echo ln(0.0) ## -inf
  281. ## echo ln(-7.0) ## nan
  282. else: # JS
  283. proc sqrt*(x: float32): float32 {.importc: "Math.sqrt", nodecl.}
  284. proc sqrt*(x: float64): float64 {.importc: "Math.sqrt", nodecl.}
  285. proc cbrt*(x: float32): float32 {.importc: "Math.cbrt", nodecl.}
  286. proc cbrt*(x: float64): float64 {.importc: "Math.cbrt", nodecl.}
  287. proc ln*(x: float32): float32 {.importc: "Math.log", nodecl.}
  288. proc ln*(x: float64): float64 {.importc: "Math.log", nodecl.}
  289. proc log*[T: SomeFloat](x, base: T): T =
  290. ## Computes the logarithm of ``x`` to base ``base``.
  291. ##
  292. ## See also:
  293. ## * `ln proc <#ln,float64>`_
  294. ## * `log10 proc <#log10,float64>`_
  295. ## * `log2 proc <#log2,float64>`_
  296. ## * `exp proc <#exp,float64>`_
  297. ##
  298. ## .. code-block:: nim
  299. ## echo log(9.0, 3.0) ## 2.0
  300. ## echo log(32.0, 2.0) ## 5.0
  301. ## echo log(0.0, 2.0) ## -inf
  302. ## echo log(-7.0, 4.0) ## nan
  303. ## echo log(8.0, -2.0) ## nan
  304. ln(x) / ln(base)
  305. when not defined(JS): # C
  306. proc log10*(x: float32): float32 {.importc: "log10f", header: "<math.h>".}
  307. proc log10*(x: float64): float64 {.importc: "log10", header: "<math.h>".}
  308. ## Computes the common logarithm (base 10) of ``x``.
  309. ##
  310. ## See also:
  311. ## * `ln proc <#ln,float64>`_
  312. ## * `log proc <#log,T,T>`_
  313. ## * `log2 proc <#log2,float64>`_
  314. ## * `exp proc <#exp,float64>`_
  315. ##
  316. ## .. code-block:: nim
  317. ## echo log10(100.0) ## 2.0
  318. ## echo log10(0.0) ## nan
  319. ## echo log10(-100.0) ## -inf
  320. proc exp*(x: float32): float32 {.importc: "expf", header: "<math.h>".}
  321. proc exp*(x: float64): float64 {.importc: "exp", header: "<math.h>".}
  322. ## Computes the exponential function of ``x`` (e^x).
  323. ##
  324. ## See also:
  325. ## * `ln proc <#ln,float64>`_
  326. ## * `log proc <#log,T,T>`_
  327. ## * `log10 proc <#log10,float64>`_
  328. ## * `log2 proc <#log2,float64>`_
  329. ##
  330. ## .. code-block:: nim
  331. ## echo exp(1.0) ## 2.718281828459045
  332. ## echo ln(exp(4.0)) ## 4.0
  333. ## echo exp(0.0) ## 1.0
  334. ## echo exp(-1.0) ## 0.3678794411714423
  335. proc sin*(x: float32): float32 {.importc: "sinf", header: "<math.h>".}
  336. proc sin*(x: float64): float64 {.importc: "sin", header: "<math.h>".}
  337. ## Computes the sine of ``x``.
  338. ##
  339. ## See also:
  340. ## * `cos proc <#cos,float64>`_
  341. ## * `tan proc <#tan,float64>`_
  342. ## * `arcsin proc <#arcsin,float64>`_
  343. ## * `sinh proc <#sinh,float64>`_
  344. ##
  345. ## .. code-block:: nim
  346. ## echo sin(PI / 6) ## 0.4999999999999999
  347. ## echo sin(degToRad(90.0)) ## 1.0
  348. proc cos*(x: float32): float32 {.importc: "cosf", header: "<math.h>".}
  349. proc cos*(x: float64): float64 {.importc: "cos", header: "<math.h>".}
  350. ## Computes the cosine of ``x``.
  351. ##
  352. ## See also:
  353. ## * `sin proc <#sin,float64>`_
  354. ## * `tan proc <#tan,float64>`_
  355. ## * `arccos proc <#arccos,float64>`_
  356. ## * `cosh proc <#cosh,float64>`_
  357. ##
  358. ## .. code-block:: nim
  359. ## echo cos(2 * PI) ## 1.0
  360. ## echo cos(degToRad(60.0)) ## 0.5000000000000001
  361. proc tan*(x: float32): float32 {.importc: "tanf", header: "<math.h>".}
  362. proc tan*(x: float64): float64 {.importc: "tan", header: "<math.h>".}
  363. ## Computes the tangent of ``x``.
  364. ##
  365. ## See also:
  366. ## * `sin proc <#sin,float64>`_
  367. ## * `cos proc <#cos,float64>`_
  368. ## * `arctan proc <#arctan,float64>`_
  369. ## * `tanh proc <#tanh,float64>`_
  370. ##
  371. ## .. code-block:: nim
  372. ## echo tan(degToRad(45.0)) ## 0.9999999999999999
  373. ## echo tan(PI / 4) ## 0.9999999999999999
  374. proc sinh*(x: float32): float32 {.importc: "sinhf", header: "<math.h>".}
  375. proc sinh*(x: float64): float64 {.importc: "sinh", header: "<math.h>".}
  376. ## Computes the `hyperbolic sine <https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions>`_ of ``x``.
  377. ##
  378. ## See also:
  379. ## * `cosh proc <#cosh,float64>`_
  380. ## * `tanh proc <#tanh,float64>`_
  381. ## * `arcsinh proc <#arcsinh,float64>`_
  382. ## * `sin proc <#sin,float64>`_
  383. ##
  384. ## .. code-block:: nim
  385. ## echo sinh(0.0) ## 0.0
  386. ## echo sinh(1.0) ## 1.175201193643801
  387. ## echo sinh(degToRad(90.0)) ## 2.301298902307295
  388. proc cosh*(x: float32): float32 {.importc: "coshf", header: "<math.h>".}
  389. proc cosh*(x: float64): float64 {.importc: "cosh", header: "<math.h>".}
  390. ## Computes the `hyperbolic cosine <https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions>`_ of ``x``.
  391. ##
  392. ## See also:
  393. ## * `sinh proc <#sinh,float64>`_
  394. ## * `tanh proc <#tanh,float64>`_
  395. ## * `arccosh proc <#arccosh,float64>`_
  396. ## * `cos proc <#cos,float64>`_
  397. ##
  398. ## .. code-block:: nim
  399. ## echo cosh(0.0) ## 1.0
  400. ## echo cosh(1.0) ## 1.543080634815244
  401. ## echo cosh(degToRad(90.0)) ## 2.509178478658057
  402. proc tanh*(x: float32): float32 {.importc: "tanhf", header: "<math.h>".}
  403. proc tanh*(x: float64): float64 {.importc: "tanh", header: "<math.h>".}
  404. ## Computes the `hyperbolic tangent <https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions>`_ of ``x``.
  405. ##
  406. ## See also:
  407. ## * `sinh proc <#sinh,float64>`_
  408. ## * `cosh proc <#cosh,float64>`_
  409. ## * `arctanh proc <#arctanh,float64>`_
  410. ## * `tan proc <#tan,float64>`_
  411. ##
  412. ## .. code-block:: nim
  413. ## echo tanh(0.0) ## 0.0
  414. ## echo tanh(1.0) ## 0.7615941559557649
  415. ## echo tanh(degToRad(90.0)) ## 0.9171523356672744
  416. proc arccos*(x: float32): float32 {.importc: "acosf", header: "<math.h>".}
  417. proc arccos*(x: float64): float64 {.importc: "acos", header: "<math.h>".}
  418. ## Computes the arc cosine of ``x``.
  419. ##
  420. ## See also:
  421. ## * `arcsin proc <#arcsin,float64>`_
  422. ## * `arctan proc <#arctan,float64>`_
  423. ## * `arctan2 proc <#arctan2,float64,float64>`_
  424. ## * `cos proc <#cos,float64>`_
  425. ##
  426. ## .. code-block:: nim
  427. ## echo radToDeg(arccos(0.0)) ## 90.0
  428. ## echo radToDeg(arccos(1.0)) ## 0.0
  429. proc arcsin*(x: float32): float32 {.importc: "asinf", header: "<math.h>".}
  430. proc arcsin*(x: float64): float64 {.importc: "asin", header: "<math.h>".}
  431. ## Computes the arc sine of ``x``.
  432. ##
  433. ## See also:
  434. ## * `arccos proc <#arccos,float64>`_
  435. ## * `arctan proc <#arctan,float64>`_
  436. ## * `arctan2 proc <#arctan2,float64,float64>`_
  437. ## * `sin proc <#sin,float64>`_
  438. ##
  439. ## .. code-block:: nim
  440. ## echo radToDeg(arcsin(0.0)) ## 0.0
  441. ## echo radToDeg(arcsin(1.0)) ## 90.0
  442. proc arctan*(x: float32): float32 {.importc: "atanf", header: "<math.h>".}
  443. proc arctan*(x: float64): float64 {.importc: "atan", header: "<math.h>".}
  444. ## Calculate the arc tangent of ``x``.
  445. ##
  446. ## See also:
  447. ## * `arcsin proc <#arcsin,float64>`_
  448. ## * `arccos proc <#arccos,float64>`_
  449. ## * `arctan2 proc <#arctan2,float64,float64>`_
  450. ## * `tan proc <#tan,float64>`_
  451. ##
  452. ## .. code-block:: nim
  453. ## echo arctan(1.0) ## 0.7853981633974483
  454. ## echo radToDeg(arctan(1.0)) ## 45.0
  455. proc arctan2*(y, x: float32): float32 {.importc: "atan2f",
  456. header: "<math.h>".}
  457. proc arctan2*(y, x: float64): float64 {.importc: "atan2", header: "<math.h>".}
  458. ## Calculate the arc tangent of ``y`` / ``x``.
  459. ##
  460. ## It produces correct results even when the resulting angle is near
  461. ## pi/2 or -pi/2 (``x`` near 0).
  462. ##
  463. ## See also:
  464. ## * `arcsin proc <#arcsin,float64>`_
  465. ## * `arccos proc <#arccos,float64>`_
  466. ## * `arctan proc <#arctan,float64>`_
  467. ## * `tan proc <#tan,float64>`_
  468. ##
  469. ## .. code-block:: nim
  470. ## echo arctan2(1.0, 0.0) ## 1.570796326794897
  471. ## echo radToDeg(arctan2(1.0, 0.0)) ## 90.0
  472. proc arcsinh*(x: float32): float32 {.importc: "asinhf", header: "<math.h>".}
  473. proc arcsinh*(x: float64): float64 {.importc: "asinh", header: "<math.h>".}
  474. ## Computes the inverse hyperbolic sine of ``x``.
  475. proc arccosh*(x: float32): float32 {.importc: "acoshf", header: "<math.h>".}
  476. proc arccosh*(x: float64): float64 {.importc: "acosh", header: "<math.h>".}
  477. ## Computes the inverse hyperbolic cosine of ``x``.
  478. proc arctanh*(x: float32): float32 {.importc: "atanhf", header: "<math.h>".}
  479. proc arctanh*(x: float64): float64 {.importc: "atanh", header: "<math.h>".}
  480. ## Computes the inverse hyperbolic tangent of ``x``.
  481. else: # JS
  482. proc log10*(x: float32): float32 {.importc: "Math.log10", nodecl.}
  483. proc log10*(x: float64): float64 {.importc: "Math.log10", nodecl.}
  484. proc log2*(x: float32): float32 {.importc: "Math.log2", nodecl.}
  485. proc log2*(x: float64): float64 {.importc: "Math.log2", nodecl.}
  486. proc exp*(x: float32): float32 {.importc: "Math.exp", nodecl.}
  487. proc exp*(x: float64): float64 {.importc: "Math.exp", nodecl.}
  488. proc sin*[T: float32|float64](x: T): T {.importc: "Math.sin", nodecl.}
  489. proc cos*[T: float32|float64](x: T): T {.importc: "Math.cos", nodecl.}
  490. proc tan*[T: float32|float64](x: T): T {.importc: "Math.tan", nodecl.}
  491. proc sinh*[T: float32|float64](x: T): T {.importc: "Math.sinh", nodecl.}
  492. proc cosh*[T: float32|float64](x: T): T {.importc: "Math.cosh", nodecl.}
  493. proc tanh*[T: float32|float64](x: T): T {.importc: "Math.tanh", nodecl.}
  494. proc arcsin*[T: float32|float64](x: T): T {.importc: "Math.asin", nodecl.}
  495. proc arccos*[T: float32|float64](x: T): T {.importc: "Math.acos", nodecl.}
  496. proc arctan*[T: float32|float64](x: T): T {.importc: "Math.atan", nodecl.}
  497. proc arctan2*[T: float32|float64](y, x: T): T {.importc: "Math.atan2", nodecl.}
  498. proc arcsinh*[T: float32|float64](x: T): T {.importc: "Math.asinh", nodecl.}
  499. proc arccosh*[T: float32|float64](x: T): T {.importc: "Math.acosh", nodecl.}
  500. proc arctanh*[T: float32|float64](x: T): T {.importc: "Math.atanh", nodecl.}
  501. proc cot*[T: float32|float64](x: T): T = 1.0 / tan(x)
  502. ## Computes the cotangent of ``x`` (1 / tan(x)).
  503. proc sec*[T: float32|float64](x: T): T = 1.0 / cos(x)
  504. ## Computes the secant of ``x`` (1 / cos(x)).
  505. proc csc*[T: float32|float64](x: T): T = 1.0 / sin(x)
  506. ## Computes the cosecant of ``x`` (1 / sin(x)).
  507. proc coth*[T: float32|float64](x: T): T = 1.0 / tanh(x)
  508. ## Computes the hyperbolic cotangent of ``x`` (1 / tanh(x)).
  509. proc sech*[T: float32|float64](x: T): T = 1.0 / cosh(x)
  510. ## Computes the hyperbolic secant of ``x`` (1 / cosh(x)).
  511. proc csch*[T: float32|float64](x: T): T = 1.0 / sinh(x)
  512. ## Computes the hyperbolic cosecant of ``x`` (1 / sinh(x)).
  513. proc arccot*[T: float32|float64](x: T): T = arctan(1.0 / x)
  514. ## Computes the inverse cotangent of ``x``.
  515. proc arcsec*[T: float32|float64](x: T): T = arccos(1.0 / x)
  516. ## Computes the inverse secant of ``x``.
  517. proc arccsc*[T: float32|float64](x: T): T = arcsin(1.0 / x)
  518. ## Computes the inverse cosecant of ``x``.
  519. proc arccoth*[T: float32|float64](x: T): T = arctanh(1.0 / x)
  520. ## Computes the inverse hyperbolic cotangent of ``x``.
  521. proc arcsech*[T: float32|float64](x: T): T = arccosh(1.0 / x)
  522. ## Computes the inverse hyperbolic secant of ``x``.
  523. proc arccsch*[T: float32|float64](x: T): T = arcsinh(1.0 / x)
  524. ## Computes the inverse hyperbolic cosecant of ``x``.
  525. const windowsCC89 = defined(windows) and defined(bcc)
  526. when not defined(JS): # C
  527. proc hypot*(x, y: float32): float32 {.importc: "hypotf", header: "<math.h>".}
  528. proc hypot*(x, y: float64): float64 {.importc: "hypot", header: "<math.h>".}
  529. ## Computes the hypotenuse of a right-angle triangle with ``x`` and
  530. ## ``y`` as its base and height. Equivalent to ``sqrt(x*x + y*y)``.
  531. ##
  532. ## .. code-block:: nim
  533. ## echo hypot(4.0, 3.0) ## 5.0
  534. proc pow*(x, y: float32): float32 {.importc: "powf", header: "<math.h>".}
  535. proc pow*(x, y: float64): float64 {.importc: "pow", header: "<math.h>".}
  536. ## Computes x to power raised of y.
  537. ##
  538. ## To compute power between integers (e.g. 2^6), use `^ proc<#^,T,Natural>`_.
  539. ##
  540. ## See also:
  541. ## * `^ proc<#^,T,Natural>`_
  542. ## * `sqrt proc <#sqrt,float64>`_
  543. ## * `cbrt proc <#cbrt,float64>`_
  544. ##
  545. ## .. code-block:: nim
  546. ## echo pow(100, 1.5) ## 1000.0
  547. ## echo pow(16.0, 0.5) ## 4.0
  548. # TODO: add C89 version on windows
  549. when not windowsCC89:
  550. proc erf*(x: float32): float32 {.importc: "erff", header: "<math.h>".}
  551. proc erf*(x: float64): float64 {.importc: "erf", header: "<math.h>".}
  552. ## Computes the `error function <https://en.wikipedia.org/wiki/Error_function>`_ for ``x``.
  553. ##
  554. ## Note: Not available for JS backend.
  555. proc erfc*(x: float32): float32 {.importc: "erfcf", header: "<math.h>".}
  556. proc erfc*(x: float64): float64 {.importc: "erfc", header: "<math.h>".}
  557. ## Computes the `complementary error function <https://en.wikipedia.org/wiki/Error_function#Complementary_error_function>`_ for ``x``.
  558. ##
  559. ## Note: Not available for JS backend.
  560. proc gamma*(x: float32): float32 {.importc: "tgammaf", header: "<math.h>".}
  561. proc gamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".}
  562. ## Computes the the `gamma function <https://en.wikipedia.org/wiki/Gamma_function>`_ for ``x``.
  563. ##
  564. ## Note: Not available for JS backend.
  565. ##
  566. ## See also:
  567. ## * `lgamma proc <#lgamma,float64>`_ for a natural log of gamma function
  568. ##
  569. ## .. code-block:: Nim
  570. ## echo gamma(1.0) # 1.0
  571. ## echo gamma(4.0) # 6.0
  572. ## echo gamma(11.0) # 3628800.0
  573. ## echo gamma(-1.0) # nan
  574. proc tgamma*(x: float32): float32
  575. {.deprecated: "Deprecated since v0.19.0; use 'gamma' instead",
  576. importc: "tgammaf", header: "<math.h>".}
  577. proc tgamma*(x: float64): float64
  578. {.deprecated: "Deprecated since v0.19.0; use 'gamma' instead",
  579. importc: "tgamma", header: "<math.h>".}
  580. ## The gamma function
  581. proc lgamma*(x: float32): float32 {.importc: "lgammaf", header: "<math.h>".}
  582. proc lgamma*(x: float64): float64 {.importc: "lgamma", header: "<math.h>".}
  583. ## Computes the natural log of the gamma function for ``x``.
  584. ##
  585. ## Note: Not available for JS backend.
  586. ##
  587. ## See also:
  588. ## * `gamma proc <#gamma,float64>`_ for gamma function
  589. ##
  590. ## .. code-block:: Nim
  591. ## echo lgamma(1.0) # 1.0
  592. ## echo lgamma(4.0) # 1.791759469228055
  593. ## echo lgamma(11.0) # 15.10441257307552
  594. ## echo lgamma(-1.0) # inf
  595. proc floor*(x: float32): float32 {.importc: "floorf", header: "<math.h>".}
  596. proc floor*(x: float64): float64 {.importc: "floor", header: "<math.h>".}
  597. ## Computes the floor function (i.e., the largest integer not greater than ``x``).
  598. ##
  599. ## See also:
  600. ## * `ceil proc <#ceil,float64>`_
  601. ## * `round proc <#round,float64>`_
  602. ## * `trunc proc <#trunc,float64>`_
  603. ##
  604. ## .. code-block:: nim
  605. ## echo floor(2.1) ## 2.0
  606. ## echo floor(2.9) ## 2.0
  607. ## echo floor(-3.5) ## -4.0
  608. proc ceil*(x: float32): float32 {.importc: "ceilf", header: "<math.h>".}
  609. proc ceil*(x: float64): float64 {.importc: "ceil", header: "<math.h>".}
  610. ## Computes the ceiling function (i.e., the smallest integer not smaller
  611. ## than ``x``).
  612. ##
  613. ## See also:
  614. ## * `floor proc <#floor,float64>`_
  615. ## * `round proc <#round,float64>`_
  616. ## * `trunc proc <#trunc,float64>`_
  617. ##
  618. ## .. code-block:: nim
  619. ## echo ceil(2.1) ## 3.0
  620. ## echo ceil(2.9) ## 3.0
  621. ## echo ceil(-2.1) ## -2.0
  622. when windowsCC89:
  623. # MSVC 2010 don't have trunc/truncf
  624. # this implementation was inspired by Go-lang Math.Trunc
  625. proc truncImpl(f: float64): float64 =
  626. const
  627. mask: uint64 = 0x7FF
  628. shift: uint64 = 64 - 12
  629. bias: uint64 = 0x3FF
  630. if f < 1:
  631. if f < 0: return -truncImpl(-f)
  632. elif f == 0: return f # Return -0 when f == -0
  633. else: return 0
  634. var x = cast[uint64](f)
  635. let e = (x shr shift) and mask - bias
  636. # Keep the top 12+e bits, the integer part; clear the rest.
  637. if e < 64-12:
  638. x = x and (not (1'u64 shl (64'u64-12'u64-e) - 1'u64))
  639. result = cast[float64](x)
  640. proc truncImpl(f: float32): float32 =
  641. const
  642. mask: uint32 = 0xFF
  643. shift: uint32 = 32 - 9
  644. bias: uint32 = 0x7F
  645. if f < 1:
  646. if f < 0: return -truncImpl(-f)
  647. elif f == 0: return f # Return -0 when f == -0
  648. else: return 0
  649. var x = cast[uint32](f)
  650. let e = (x shr shift) and mask - bias
  651. # Keep the top 9+e bits, the integer part; clear the rest.
  652. if e < 32-9:
  653. x = x and (not (1'u32 shl (32'u32-9'u32-e) - 1'u32))
  654. result = cast[float32](x)
  655. proc trunc*(x: float64): float64 =
  656. if classify(x) in {fcZero, fcNegZero, fcNan, fcInf, fcNegInf}: return x
  657. result = truncImpl(x)
  658. proc trunc*(x: float32): float32 =
  659. if classify(x) in {fcZero, fcNegZero, fcNan, fcInf, fcNegInf}: return x
  660. result = truncImpl(x)
  661. proc round*[T: float32|float64](x: T): T =
  662. ## Windows compilers prior to MSVC 2012 do not implement 'round',
  663. ## 'roundl' or 'roundf'.
  664. result = if x < 0.0: ceil(x - T(0.5)) else: floor(x + T(0.5))
  665. else:
  666. proc round*(x: float32): float32 {.importc: "roundf", header: "<math.h>".}
  667. proc round*(x: float64): float64 {.importc: "round", header: "<math.h>".}
  668. ## Rounds a float to zero decimal places.
  669. ##
  670. ## Used internally by the `round proc <#round,T,int>`_
  671. ## when the specified number of places is 0.
  672. ##
  673. ## See also:
  674. ## * `round proc <#round,T,int>`_ for rounding to the specific
  675. ## number of decimal places
  676. ## * `floor proc <#floor,float64>`_
  677. ## * `ceil proc <#ceil,float64>`_
  678. ## * `trunc proc <#trunc,float64>`_
  679. ##
  680. ## .. code-block:: nim
  681. ## echo round(3.4) ## 3.0
  682. ## echo round(3.5) ## 4.0
  683. ## echo round(4.5) ## 5.0
  684. proc trunc*(x: float32): float32 {.importc: "truncf", header: "<math.h>".}
  685. proc trunc*(x: float64): float64 {.importc: "trunc", header: "<math.h>".}
  686. ## Truncates ``x`` to the decimal point.
  687. ##
  688. ## See also:
  689. ## * `floor proc <#floor,float64>`_
  690. ## * `ceil proc <#ceil,float64>`_
  691. ## * `round proc <#round,float64>`_
  692. ##
  693. ## .. code-block:: nim
  694. ## echo trunc(PI) # 3.0
  695. ## echo trunc(-1.85) # -1.0
  696. proc fmod*(x, y: float32): float32 {.deprecated: "Deprecated since v0.19.0; use 'mod' instead",
  697. importc: "fmodf", header: "<math.h>".}
  698. proc fmod*(x, y: float64): float64 {.deprecated: "Deprecated since v0.19.0; use 'mod' instead",
  699. importc: "fmod", header: "<math.h>".}
  700. ## Computes the remainder of ``x`` divided by ``y``.
  701. proc `mod`*(x, y: float32): float32 {.importc: "fmodf", header: "<math.h>".}
  702. proc `mod`*(x, y: float64): float64 {.importc: "fmod", header: "<math.h>".}
  703. ## Computes the modulo operation for float values (the remainder of ``x`` divided by ``y``).
  704. ##
  705. ## See also:
  706. ## * `floorMod proc <#floorMod,T,T>`_ for Python-like (% operator) behavior
  707. ##
  708. ## .. code-block:: nim
  709. ## ( 6.5 mod 2.5) == 1.5
  710. ## (-6.5 mod 2.5) == -1.5
  711. ## ( 6.5 mod -2.5) == 1.5
  712. ## (-6.5 mod -2.5) == -1.5
  713. else: # JS
  714. proc hypot*(x, y: float32): float32 {.importc: "Math.hypot", varargs, nodecl.}
  715. proc hypot*(x, y: float64): float64 {.importc: "Math.hypot", varargs, nodecl.}
  716. proc pow*(x, y: float32): float32 {.importc: "Math.pow", nodecl.}
  717. proc pow*(x, y: float64): float64 {.importc: "Math.pow", nodecl.}
  718. proc floor*(x: float32): float32 {.importc: "Math.floor", nodecl.}
  719. proc floor*(x: float64): float64 {.importc: "Math.floor", nodecl.}
  720. proc ceil*(x: float32): float32 {.importc: "Math.ceil", nodecl.}
  721. proc ceil*(x: float64): float64 {.importc: "Math.ceil", nodecl.}
  722. proc round*(x: float): float {.importc: "Math.round", nodecl.}
  723. proc trunc*(x: float32): float32 {.importc: "Math.trunc", nodecl.}
  724. proc trunc*(x: float64): float64 {.importc: "Math.trunc", nodecl.}
  725. proc `mod`*(x, y: float32): float32 {.importcpp: "# % #".}
  726. proc `mod`*(x, y: float64): float64 {.importcpp: "# % #".}
  727. ## Computes the modulo operation for float values (the remainder of ``x`` divided by ``y``).
  728. ##
  729. ## .. code-block:: nim
  730. ## ( 6.5 mod 2.5) == 1.5
  731. ## (-6.5 mod 2.5) == -1.5
  732. ## ( 6.5 mod -2.5) == 1.5
  733. ## (-6.5 mod -2.5) == -1.5
  734. proc round*[T: float32|float64](x: T, places: int): T {.
  735. deprecated: "use strformat module instead".} =
  736. ## Decimal rounding on a binary floating point number.
  737. ##
  738. ## This function is NOT reliable. Floating point numbers cannot hold
  739. ## non integer decimals precisely. If ``places`` is 0 (or omitted),
  740. ## round to the nearest integral value following normal mathematical
  741. ## rounding rules (e.g. ``round(54.5) -> 55.0``). If ``places`` is
  742. ## greater than 0, round to the given number of decimal places,
  743. ## e.g. ``round(54.346, 2) -> 54.350000000000001421…``. If ``places`` is negative, round
  744. ## to the left of the decimal place, e.g. ``round(537.345, -1) ->
  745. ## 540.0``
  746. ##
  747. ## .. code-block:: Nim
  748. ## echo round(PI, 2) ## 3.14
  749. ## echo round(PI, 4) ## 3.1416
  750. if places == 0:
  751. result = round(x)
  752. else:
  753. var mult = pow(10.0, places.T)
  754. result = round(x*mult)/mult
  755. proc floorDiv*[T: SomeInteger](x, y: T): T =
  756. ## Floor division is conceptually defined as ``floor(x / y)``.
  757. ##
  758. ## This is different from the `system.div <system.html#div,int,int>`_
  759. ## operator, which is defined as ``trunc(x / y)``.
  760. ## That is, ``div`` rounds towards ``0`` and ``floorDiv`` rounds down.
  761. ##
  762. ## See also:
  763. ## * `system.div proc <system.html#div,int,int>`_ for integer division
  764. ## * `floorMod proc <#floorMod,T,T>`_ for Python-like (% operator) behavior
  765. ##
  766. ## .. code-block:: nim
  767. ## echo floorDiv( 13, 3) # 4
  768. ## echo floorDiv(-13, 3) # -5
  769. ## echo floorDiv( 13, -3) # -5
  770. ## echo floorDiv(-13, -3) # 4
  771. result = x div y
  772. let r = x mod y
  773. if (r > 0 and y < 0) or (r < 0 and y > 0): result.dec 1
  774. proc floorMod*[T: SomeNumber](x, y: T): T =
  775. ## Floor modulus is conceptually defined as ``x - (floorDiv(x, y) * y)``.
  776. ##
  777. ## This proc behaves the same as the ``%`` operator in Python.
  778. ##
  779. ## See also:
  780. ## * `mod proc <#mod,float64,float64>`_
  781. ## * `floorDiv proc <#floorDiv,T,T>`_
  782. ##
  783. ## .. code-block:: nim
  784. ## echo floorMod( 13, 3) # 1
  785. ## echo floorMod(-13, 3) # 2
  786. ## echo floorMod( 13, -3) # -2
  787. ## echo floorMod(-13, -3) # -1
  788. result = x mod y
  789. if (result > 0 and y < 0) or (result < 0 and y > 0): result += y
  790. when not defined(JS):
  791. proc c_frexp*(x: float32, exponent: var int32): float32 {.
  792. importc: "frexp", header: "<math.h>".}
  793. proc c_frexp*(x: float64, exponent: var int32): float64 {.
  794. importc: "frexp", header: "<math.h>".}
  795. proc frexp*[T, U](x: T, exponent: var U): T =
  796. ## Split a number into mantissa and exponent.
  797. ##
  798. ## ``frexp`` calculates the mantissa m (a float greater than or equal to 0.5
  799. ## and less than 1) and the integer value n such that ``x`` (the original
  800. ## float value) equals ``m * 2**n``. frexp stores n in `exponent` and returns
  801. ## m.
  802. ##
  803. ## .. code-block:: nim
  804. ## var x: int
  805. ## echo frexp(5.0, x) # 0.625
  806. ## echo x # 3
  807. var exp: int32
  808. result = c_frexp(x, exp)
  809. exponent = exp
  810. when windowsCC89:
  811. # taken from Go-lang Math.Log2
  812. const ln2 = 0.693147180559945309417232121458176568075500134360255254120680009
  813. template log2Impl[T](x: T): T =
  814. var exp: int32
  815. var frac = frexp(x, exp)
  816. # Make sure exact powers of two give an exact answer.
  817. # Don't depend on Log(0.5)*(1/Ln2)+exp being exactly exp-1.
  818. if frac == 0.5: return T(exp - 1)
  819. log10(frac)*(1/ln2) + T(exp)
  820. proc log2*(x: float32): float32 = log2Impl(x)
  821. proc log2*(x: float64): float64 = log2Impl(x)
  822. ## Log2 returns the binary logarithm of x.
  823. ## The special cases are the same as for Log.
  824. else:
  825. proc log2*(x: float32): float32 {.importc: "log2f", header: "<math.h>".}
  826. proc log2*(x: float64): float64 {.importc: "log2", header: "<math.h>".}
  827. ## Computes the binary logarithm (base 2) of ``x``.
  828. ##
  829. ## See also:
  830. ## * `log proc <#log,T,T>`_
  831. ## * `log10 proc <#log10,float64>`_
  832. ## * `ln proc <#ln,float64>`_
  833. ## * `exp proc <#exp,float64>`_
  834. ##
  835. ## .. code-block:: Nim
  836. ## echo log2(8.0) # 3.0
  837. ## echo log2(1.0) # 0.0
  838. ## echo log2(0.0) # -inf
  839. ## echo log2(-2.0) # nan
  840. else:
  841. proc frexp*[T: float32|float64](x: T, exponent: var int): T =
  842. if x == 0.0:
  843. exponent = 0
  844. result = 0.0
  845. elif x < 0.0:
  846. result = -frexp(-x, exponent)
  847. else:
  848. var ex = trunc(log2(x))
  849. exponent = int(ex)
  850. result = x / pow(2.0, ex)
  851. if abs(result) >= 1:
  852. inc(exponent)
  853. result = result / 2
  854. if exponent == 1024 and result == 0.0:
  855. result = 0.99999999999999988898
  856. proc splitDecimal*[T: float32|float64](x: T): tuple[intpart: T, floatpart: T] =
  857. ## Breaks ``x`` into an integer and a fractional part.
  858. ##
  859. ## Returns a tuple containing ``intpart`` and ``floatpart`` representing
  860. ## the integer part and the fractional part respectively.
  861. ##
  862. ## Both parts have the same sign as ``x``. Analogous to the ``modf``
  863. ## function in C.
  864. ##
  865. ## .. code-block:: nim
  866. ## echo splitDecimal(5.25) # (intpart: 5.0, floatpart: 0.25)
  867. ## echo splitDecimal(-2.73) # (intpart: -2.0, floatpart: -0.73)
  868. var
  869. absolute: T
  870. absolute = abs(x)
  871. result.intpart = floor(absolute)
  872. result.floatpart = absolute - result.intpart
  873. if x < 0:
  874. result.intpart = -result.intpart
  875. result.floatpart = -result.floatpart
  876. {.pop.}
  877. proc degToRad*[T: float32|float64](d: T): T {.inline.} =
  878. ## Convert from degrees to radians.
  879. ##
  880. ## See also:
  881. ## * `radToDeg proc <#radToDeg,T>`_
  882. ##
  883. ## .. code-block:: nim
  884. ## echo degToRad(180.0) # 3.141592653589793
  885. result = T(d) * RadPerDeg
  886. proc radToDeg*[T: float32|float64](d: T): T {.inline.} =
  887. ## Convert from radians to degrees.
  888. ##
  889. ## See also:
  890. ## * `degToRad proc <#degToRad,T>`_
  891. ##
  892. ## .. code-block:: nim
  893. ## echo degToRad(2 * PI) # 360.0
  894. result = T(d) / RadPerDeg
  895. proc sgn*[T: SomeNumber](x: T): int {.inline.} =
  896. ## Sign function.
  897. ##
  898. ## Returns:
  899. ## * `-1` for negative numbers and ``NegInf``,
  900. ## * `1` for positive numbers and ``Inf``,
  901. ## * `0` for positive zero, negative zero and ``NaN``
  902. ##
  903. ## .. code-block:: nim
  904. ## echo sgn(5) # 1
  905. ## echo sgn(0) # 0
  906. ## echo sgn(-4.1) # -1
  907. ord(T(0) < x) - ord(x < T(0))
  908. {.pop.}
  909. {.pop.}
  910. proc `^`*[T](x: T, y: Natural): T =
  911. ## Computes ``x`` to the power ``y``.
  912. ##
  913. ## Exponent ``y`` must be non-negative, use
  914. ## `pow proc <#pow,float64,float64>`_ for negative exponents.
  915. ##
  916. ## See also:
  917. ## * `pow proc <#pow,float64,float64>`_ for negative exponent or
  918. ## floats
  919. ## * `sqrt proc <#sqrt,float64>`_
  920. ## * `cbrt proc <#cbrt,float64>`_
  921. ##
  922. runnableExamples:
  923. assert -3.0^0 == 1.0
  924. assert -3^1 == -3
  925. assert -3^2 == 9
  926. assert -3.0^3 == -27.0
  927. assert -3.0^4 == 81.0
  928. case y
  929. of 0: result = 1
  930. of 1: result = x
  931. of 2: result = x * x
  932. of 3: result = x * x * x
  933. else:
  934. var (x, y) = (x, y)
  935. result = 1
  936. while true:
  937. if (y and 1) != 0:
  938. result *= x
  939. y = y shr 1
  940. if y == 0:
  941. break
  942. x *= x
  943. proc gcd*[T](x, y: T): T =
  944. ## Computes the greatest common (positive) divisor of ``x`` and ``y``.
  945. ##
  946. ## Note that for floats, the result cannot always be interpreted as
  947. ## "greatest decimal `z` such that ``z*N == x and z*M == y``
  948. ## where N and M are positive integers."
  949. ##
  950. ## See also:
  951. ## * `gcd proc <#gcd,SomeInteger,SomeInteger>`_ for integer version
  952. ## * `lcm proc <#lcm,T,T>`_
  953. runnableExamples:
  954. doAssert gcd(13.5, 9.0) == 4.5
  955. var (x, y) = (x, y)
  956. while y != 0:
  957. x = x mod y
  958. swap x, y
  959. abs x
  960. proc gcd*(x, y: SomeInteger): SomeInteger =
  961. ## Computes the greatest common (positive) divisor of ``x`` and ``y``,
  962. ## using binary GCD (aka Stein's) algorithm.
  963. ##
  964. ## See also:
  965. ## * `gcd proc <#gcd,T,T>`_ for floats version
  966. ## * `lcm proc <#lcm,T,T>`_
  967. runnableExamples:
  968. doAssert gcd(12, 8) == 4
  969. doAssert gcd(17, 63) == 1
  970. when x is SomeSignedInt:
  971. var x = abs(x)
  972. else:
  973. var x = x
  974. when y is SomeSignedInt:
  975. var y = abs(y)
  976. else:
  977. var y = y
  978. if x == 0:
  979. return y
  980. if y == 0:
  981. return x
  982. let shift = countTrailingZeroBits(x or y)
  983. y = y shr countTrailingZeroBits(y)
  984. while x != 0:
  985. x = x shr countTrailingZeroBits(x)
  986. if y > x:
  987. swap y, x
  988. x -= y
  989. y shl shift
  990. proc gcd*[T](x: openArray[T]): T {.since: (1, 1).} =
  991. ## Computes the greatest common (positive) divisor of the elements of ``x``.
  992. ##
  993. ## See also:
  994. ## * `gcd proc <#gcd,T,T>`_ for integer version
  995. runnableExamples:
  996. doAssert gcd(@[13.5, 9.0]) == 4.5
  997. result = x[0]
  998. var i = 1
  999. while i < x.len:
  1000. result = gcd(result, x[i])
  1001. inc(i)
  1002. proc lcm*[T](x, y: T): T =
  1003. ## Computes the least common multiple of ``x`` and ``y``.
  1004. ##
  1005. ## See also:
  1006. ## * `gcd proc <#gcd,T,T>`_
  1007. runnableExamples:
  1008. doAssert lcm(24, 30) == 120
  1009. doAssert lcm(13, 39) == 39
  1010. x div gcd(x, y) * y
  1011. proc lcm*[T](x: openArray[T]): T {.since: (1, 1).} =
  1012. ## Computes the least common multiple of the elements of ``x``.
  1013. ##
  1014. ## See also:
  1015. ## * `gcd proc <#gcd,T,T>`_ for integer version
  1016. runnableExamples:
  1017. doAssert lcm(@[24, 30]) == 120
  1018. result = x[0]
  1019. var i = 1
  1020. while i < x.len:
  1021. result = lcm(result, x[i])
  1022. inc(i)
  1023. when isMainModule and not defined(JS) and not windowsCC89:
  1024. # Check for no side effect annotation
  1025. proc mySqrt(num: float): float {.noSideEffect.} =
  1026. return sqrt(num)
  1027. # check gamma function
  1028. assert(gamma(5.0) == 24.0) # 4!
  1029. assert($tgamma(5.0) == $24.0) # 4!
  1030. assert(lgamma(1.0) == 0.0) # ln(1.0) == 0.0
  1031. assert(erf(6.0) > erf(5.0))
  1032. assert(erfc(6.0) < erfc(5.0))
  1033. when isMainModule:
  1034. # Function for approximate comparison of floats
  1035. proc `==~`(x, y: float): bool = (abs(x-y) < 1e-9)
  1036. block: # prod
  1037. doAssert prod([1, 2, 3, 4]) == 24
  1038. doAssert prod([1.5, 3.4]) == 5.1
  1039. let x: seq[float] = @[]
  1040. doAssert prod(x) == 1.0
  1041. block: # round() tests
  1042. # Round to 0 decimal places
  1043. doAssert round(54.652) ==~ 55.0
  1044. doAssert round(54.352) ==~ 54.0
  1045. doAssert round(-54.652) ==~ -55.0
  1046. doAssert round(-54.352) ==~ -54.0
  1047. doAssert round(0.0) ==~ 0.0
  1048. # Round to positive decimal places
  1049. doAssert round(-547.652, 1) ==~ -547.7
  1050. doAssert round(547.652, 1) ==~ 547.7
  1051. doAssert round(-547.652, 2) ==~ -547.65
  1052. doAssert round(547.652, 2) ==~ 547.65
  1053. # Round to negative decimal places
  1054. doAssert round(547.652, -1) ==~ 550.0
  1055. doAssert round(547.652, -2) ==~ 500.0
  1056. doAssert round(547.652, -3) ==~ 1000.0
  1057. doAssert round(547.652, -4) ==~ 0.0
  1058. doAssert round(-547.652, -1) ==~ -550.0
  1059. doAssert round(-547.652, -2) ==~ -500.0
  1060. doAssert round(-547.652, -3) ==~ -1000.0
  1061. doAssert round(-547.652, -4) ==~ 0.0
  1062. block: # splitDecimal() tests
  1063. doAssert splitDecimal(54.674).intpart ==~ 54.0
  1064. doAssert splitDecimal(54.674).floatpart ==~ 0.674
  1065. doAssert splitDecimal(-693.4356).intpart ==~ -693.0
  1066. doAssert splitDecimal(-693.4356).floatpart ==~ -0.4356
  1067. doAssert splitDecimal(0.0).intpart ==~ 0.0
  1068. doAssert splitDecimal(0.0).floatpart ==~ 0.0
  1069. block: # trunc tests for vcc
  1070. doAssert(trunc(-1.1) == -1)
  1071. doAssert(trunc(1.1) == 1)
  1072. doAssert(trunc(-0.1) == -0)
  1073. doAssert(trunc(0.1) == 0)
  1074. #special case
  1075. doAssert(classify(trunc(1e1000000)) == fcInf)
  1076. doAssert(classify(trunc(-1e1000000)) == fcNegInf)
  1077. doAssert(classify(trunc(0.0/0.0)) == fcNan)
  1078. doAssert(classify(trunc(0.0)) == fcZero)
  1079. #trick the compiler to produce signed zero
  1080. let
  1081. f_neg_one = -1.0
  1082. f_zero = 0.0
  1083. f_nan = f_zero / f_zero
  1084. doAssert(classify(trunc(f_neg_one*f_zero)) == fcNegZero)
  1085. doAssert(trunc(-1.1'f32) == -1)
  1086. doAssert(trunc(1.1'f32) == 1)
  1087. doAssert(trunc(-0.1'f32) == -0)
  1088. doAssert(trunc(0.1'f32) == 0)
  1089. doAssert(classify(trunc(1e1000000'f32)) == fcInf)
  1090. doAssert(classify(trunc(-1e1000000'f32)) == fcNegInf)
  1091. doAssert(classify(trunc(f_nan.float32)) == fcNan)
  1092. doAssert(classify(trunc(0.0'f32)) == fcZero)
  1093. block: # sgn() tests
  1094. assert sgn(1'i8) == 1
  1095. assert sgn(1'i16) == 1
  1096. assert sgn(1'i32) == 1
  1097. assert sgn(1'i64) == 1
  1098. assert sgn(1'u8) == 1
  1099. assert sgn(1'u16) == 1
  1100. assert sgn(1'u32) == 1
  1101. assert sgn(1'u64) == 1
  1102. assert sgn(-12342.8844'f32) == -1
  1103. assert sgn(123.9834'f64) == 1
  1104. assert sgn(0'i32) == 0
  1105. assert sgn(0'f32) == 0
  1106. assert sgn(NegInf) == -1
  1107. assert sgn(Inf) == 1
  1108. assert sgn(NaN) == 0
  1109. block: # fac() tests
  1110. try:
  1111. discard fac(-1)
  1112. except AssertionError:
  1113. discard
  1114. doAssert fac(0) == 1
  1115. doAssert fac(1) == 1
  1116. doAssert fac(2) == 2
  1117. doAssert fac(3) == 6
  1118. doAssert fac(4) == 24
  1119. block: # floorMod/floorDiv
  1120. doAssert floorDiv(8, 3) == 2
  1121. doAssert floorMod(8, 3) == 2
  1122. doAssert floorDiv(8, -3) == -3
  1123. doAssert floorMod(8, -3) == -1
  1124. doAssert floorDiv(-8, 3) == -3
  1125. doAssert floorMod(-8, 3) == 1
  1126. doAssert floorDiv(-8, -3) == 2
  1127. doAssert floorMod(-8, -3) == -2
  1128. doAssert floorMod(8.0, -3.0) ==~ -1.0
  1129. doAssert floorMod(-8.5, 3.0) ==~ 0.5
  1130. block: # log
  1131. doAssert log(4.0, 3.0) ==~ ln(4.0) / ln(3.0)
  1132. doAssert log2(8.0'f64) == 3.0'f64
  1133. doAssert log2(4.0'f64) == 2.0'f64
  1134. doAssert log2(2.0'f64) == 1.0'f64
  1135. doAssert log2(1.0'f64) == 0.0'f64
  1136. doAssert classify(log2(0.0'f64)) == fcNegInf
  1137. doAssert log2(8.0'f32) == 3.0'f32
  1138. doAssert log2(4.0'f32) == 2.0'f32
  1139. doAssert log2(2.0'f32) == 1.0'f32
  1140. doAssert log2(1.0'f32) == 0.0'f32
  1141. doAssert classify(log2(0.0'f32)) == fcNegInf