math.nim 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229
  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. import std/private/since
  53. {.push debugger: off.} # the user does not want to trace a part
  54. # of the standard library!
  55. import bitops, fenv
  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 almostEqual*[T: SomeFloat](x, y: T; unitsInLastPlace: Natural = 4): bool {.
  147. since: (1, 5), inline, noSideEffect.} =
  148. ## Checks if two float values are almost equal, using
  149. ## `machine epsilon <https://en.wikipedia.org/wiki/Machine_epsilon>`_.
  150. ##
  151. ## `unitsInLastPlace` is the max number of
  152. ## `units in last place <https://en.wikipedia.org/wiki/Unit_in_the_last_place>`_
  153. ## difference tolerated when comparing two numbers. The larger the value, the
  154. ## more error is allowed. A ``0`` value means that two numbers must be exactly the
  155. ## same to be considered equal.
  156. ##
  157. ## The machine epsilon has to be scaled to the magnitude of the values used
  158. ## and multiplied by the desired precision in ULPs unless the difference is
  159. ## subnormal.
  160. ##
  161. # taken from: https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
  162. runnableExamples:
  163. doAssert almostEqual(3.141592653589793, 3.1415926535897936)
  164. doAssert almostEqual(1.6777215e7'f32, 1.6777216e7'f32)
  165. let diff = abs(x - y)
  166. result = diff <= epsilon(T) * abs(x + y) * T(unitsInLastPlace) or
  167. diff < minimumPositiveValue(T)
  168. proc isPowerOfTwo*(x: int): bool {.noSideEffect.} =
  169. ## Returns ``true``, if ``x`` is a power of two, ``false`` otherwise.
  170. ##
  171. ## Zero and negative numbers are not a power of two.
  172. ##
  173. ## See also:
  174. ## * `nextPowerOfTwo proc<#nextPowerOfTwo,int>`_
  175. runnableExamples:
  176. doAssert isPowerOfTwo(16) == true
  177. doAssert isPowerOfTwo(5) == false
  178. doAssert isPowerOfTwo(0) == false
  179. doAssert isPowerOfTwo(-16) == false
  180. return (x > 0) and ((x and (x - 1)) == 0)
  181. proc nextPowerOfTwo*(x: int): int {.noSideEffect.} =
  182. ## Returns ``x`` rounded up to the nearest power of two.
  183. ##
  184. ## Zero and negative numbers get rounded up to 1.
  185. ##
  186. ## See also:
  187. ## * `isPowerOfTwo proc<#isPowerOfTwo,int>`_
  188. runnableExamples:
  189. doAssert nextPowerOfTwo(16) == 16
  190. doAssert nextPowerOfTwo(5) == 8
  191. doAssert nextPowerOfTwo(0) == 1
  192. doAssert nextPowerOfTwo(-16) == 1
  193. result = x - 1
  194. when defined(cpu64):
  195. result = result or (result shr 32)
  196. when sizeof(int) > 2:
  197. result = result or (result shr 16)
  198. when sizeof(int) > 1:
  199. result = result or (result shr 8)
  200. result = result or (result shr 4)
  201. result = result or (result shr 2)
  202. result = result or (result shr 1)
  203. result += 1 + ord(x <= 0)
  204. proc sum*[T](x: openArray[T]): T {.noSideEffect.} =
  205. ## Computes the sum of the elements in ``x``.
  206. ##
  207. ## If ``x`` is empty, 0 is returned.
  208. ##
  209. ## See also:
  210. ## * `prod proc <#prod,openArray[T]>`_
  211. ## * `cumsum proc <#cumsum,openArray[T]>`_
  212. ## * `cumsummed proc <#cumsummed,openArray[T]>`_
  213. runnableExamples:
  214. doAssert sum([1, 2, 3, 4]) == 10
  215. doAssert sum([-1.5, 2.7, -0.1]) == 1.1
  216. for i in items(x): result = result + i
  217. proc prod*[T](x: openArray[T]): T {.noSideEffect.} =
  218. ## Computes the product of the elements in ``x``.
  219. ##
  220. ## If ``x`` is empty, 1 is returned.
  221. ##
  222. ## See also:
  223. ## * `sum proc <#sum,openArray[T]>`_
  224. ## * `fac proc <#fac,int>`_
  225. runnableExamples:
  226. doAssert prod([1, 2, 3, 4]) == 24
  227. doAssert prod([-4, 3, 5]) == -60
  228. result = 1.T
  229. for i in items(x): result = result * i
  230. proc cumsummed*[T](x: openArray[T]): seq[T] =
  231. ## Return cumulative (aka prefix) summation of ``x``.
  232. ##
  233. ## See also:
  234. ## * `sum proc <#sum,openArray[T]>`_
  235. ## * `cumsum proc <#cumsum,openArray[T]>`_ for the in-place version
  236. runnableExamples:
  237. let a = [1, 2, 3, 4]
  238. doAssert cumsummed(a) == @[1, 3, 6, 10]
  239. result.setLen(x.len)
  240. result[0] = x[0]
  241. for i in 1 ..< x.len: result[i] = result[i-1] + x[i]
  242. proc cumsum*[T](x: var openArray[T]) =
  243. ## Transforms ``x`` in-place (must be declared as `var`) into its
  244. ## cumulative (aka prefix) summation.
  245. ##
  246. ## See also:
  247. ## * `sum proc <#sum,openArray[T]>`_
  248. ## * `cumsummed proc <#cumsummed,openArray[T]>`_ for a version which
  249. ## returns cumsummed sequence
  250. runnableExamples:
  251. var a = [1, 2, 3, 4]
  252. cumsum(a)
  253. doAssert a == @[1, 3, 6, 10]
  254. for i in 1 ..< x.len: x[i] = x[i-1] + x[i]
  255. {.push noSideEffect.}
  256. when not defined(js): # C
  257. proc sqrt*(x: float32): float32 {.importc: "sqrtf", header: "<math.h>".}
  258. proc sqrt*(x: float64): float64 {.importc: "sqrt", header: "<math.h>".}
  259. ## Computes the square root of ``x``.
  260. ##
  261. ## See also:
  262. ## * `cbrt proc <#cbrt,float64>`_ for cubic root
  263. ##
  264. ## .. code-block:: nim
  265. ## echo sqrt(4.0) ## 2.0
  266. ## echo sqrt(1.44) ## 1.2
  267. ## echo sqrt(-4.0) ## nan
  268. proc cbrt*(x: float32): float32 {.importc: "cbrtf", header: "<math.h>".}
  269. proc cbrt*(x: float64): float64 {.importc: "cbrt", header: "<math.h>".}
  270. ## Computes the cubic root of ``x``.
  271. ##
  272. ## See also:
  273. ## * `sqrt proc <#sqrt,float64>`_ for square root
  274. ##
  275. ## .. code-block:: nim
  276. ## echo cbrt(8.0) ## 2.0
  277. ## echo cbrt(2.197) ## 1.3
  278. ## echo cbrt(-27.0) ## -3.0
  279. proc ln*(x: float32): float32 {.importc: "logf", header: "<math.h>".}
  280. proc ln*(x: float64): float64 {.importc: "log", header: "<math.h>".}
  281. ## Computes the `natural logarithm <https://en.wikipedia.org/wiki/Natural_logarithm>`_
  282. ## of ``x``.
  283. ##
  284. ## See also:
  285. ## * `log proc <#log,T,T>`_
  286. ## * `log10 proc <#log10,float64>`_
  287. ## * `log2 proc <#log2,float64>`_
  288. ## * `exp proc <#exp,float64>`_
  289. ##
  290. ## .. code-block:: nim
  291. ## echo ln(exp(4.0)) ## 4.0
  292. ## echo ln(1.0)) ## 0.0
  293. ## echo ln(0.0) ## -inf
  294. ## echo ln(-7.0) ## nan
  295. else: # JS
  296. proc sqrt*(x: float32): float32 {.importc: "Math.sqrt", nodecl.}
  297. proc sqrt*(x: float64): float64 {.importc: "Math.sqrt", nodecl.}
  298. proc cbrt*(x: float32): float32 {.importc: "Math.cbrt", nodecl.}
  299. proc cbrt*(x: float64): float64 {.importc: "Math.cbrt", nodecl.}
  300. proc ln*(x: float32): float32 {.importc: "Math.log", nodecl.}
  301. proc ln*(x: float64): float64 {.importc: "Math.log", nodecl.}
  302. proc log*[T: SomeFloat](x, base: T): T =
  303. ## Computes the logarithm of ``x`` to base ``base``.
  304. ##
  305. ## See also:
  306. ## * `ln proc <#ln,float64>`_
  307. ## * `log10 proc <#log10,float64>`_
  308. ## * `log2 proc <#log2,float64>`_
  309. ## * `exp proc <#exp,float64>`_
  310. ##
  311. ## .. code-block:: nim
  312. ## echo log(9.0, 3.0) ## 2.0
  313. ## echo log(32.0, 2.0) ## 5.0
  314. ## echo log(0.0, 2.0) ## -inf
  315. ## echo log(-7.0, 4.0) ## nan
  316. ## echo log(8.0, -2.0) ## nan
  317. ln(x) / ln(base)
  318. when not defined(js): # C
  319. proc log10*(x: float32): float32 {.importc: "log10f", header: "<math.h>".}
  320. proc log10*(x: float64): float64 {.importc: "log10", header: "<math.h>".}
  321. ## Computes the common logarithm (base 10) of ``x``.
  322. ##
  323. ## See also:
  324. ## * `ln proc <#ln,float64>`_
  325. ## * `log proc <#log,T,T>`_
  326. ## * `log2 proc <#log2,float64>`_
  327. ## * `exp proc <#exp,float64>`_
  328. ##
  329. ## .. code-block:: nim
  330. ## echo log10(100.0) ## 2.0
  331. ## echo log10(0.0) ## nan
  332. ## echo log10(-100.0) ## -inf
  333. proc exp*(x: float32): float32 {.importc: "expf", header: "<math.h>".}
  334. proc exp*(x: float64): float64 {.importc: "exp", header: "<math.h>".}
  335. ## Computes the exponential function of ``x`` (e^x).
  336. ##
  337. ## See also:
  338. ## * `ln proc <#ln,float64>`_
  339. ## * `log proc <#log,T,T>`_
  340. ## * `log10 proc <#log10,float64>`_
  341. ## * `log2 proc <#log2,float64>`_
  342. ##
  343. ## .. code-block:: nim
  344. ## echo exp(1.0) ## 2.718281828459045
  345. ## echo ln(exp(4.0)) ## 4.0
  346. ## echo exp(0.0) ## 1.0
  347. ## echo exp(-1.0) ## 0.3678794411714423
  348. proc sin*(x: float32): float32 {.importc: "sinf", header: "<math.h>".}
  349. proc sin*(x: float64): float64 {.importc: "sin", header: "<math.h>".}
  350. ## Computes the sine of ``x``.
  351. ##
  352. ## See also:
  353. ## * `cos proc <#cos,float64>`_
  354. ## * `tan proc <#tan,float64>`_
  355. ## * `arcsin proc <#arcsin,float64>`_
  356. ## * `sinh proc <#sinh,float64>`_
  357. ##
  358. ## .. code-block:: nim
  359. ## echo sin(PI / 6) ## 0.4999999999999999
  360. ## echo sin(degToRad(90.0)) ## 1.0
  361. proc cos*(x: float32): float32 {.importc: "cosf", header: "<math.h>".}
  362. proc cos*(x: float64): float64 {.importc: "cos", header: "<math.h>".}
  363. ## Computes the cosine of ``x``.
  364. ##
  365. ## See also:
  366. ## * `sin proc <#sin,float64>`_
  367. ## * `tan proc <#tan,float64>`_
  368. ## * `arccos proc <#arccos,float64>`_
  369. ## * `cosh proc <#cosh,float64>`_
  370. ##
  371. ## .. code-block:: nim
  372. ## echo cos(2 * PI) ## 1.0
  373. ## echo cos(degToRad(60.0)) ## 0.5000000000000001
  374. proc tan*(x: float32): float32 {.importc: "tanf", header: "<math.h>".}
  375. proc tan*(x: float64): float64 {.importc: "tan", header: "<math.h>".}
  376. ## Computes the tangent of ``x``.
  377. ##
  378. ## See also:
  379. ## * `sin proc <#sin,float64>`_
  380. ## * `cos proc <#cos,float64>`_
  381. ## * `arctan proc <#arctan,float64>`_
  382. ## * `tanh proc <#tanh,float64>`_
  383. ##
  384. ## .. code-block:: nim
  385. ## echo tan(degToRad(45.0)) ## 0.9999999999999999
  386. ## echo tan(PI / 4) ## 0.9999999999999999
  387. proc sinh*(x: float32): float32 {.importc: "sinhf", header: "<math.h>".}
  388. proc sinh*(x: float64): float64 {.importc: "sinh", header: "<math.h>".}
  389. ## Computes the `hyperbolic sine <https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions>`_ of ``x``.
  390. ##
  391. ## See also:
  392. ## * `cosh proc <#cosh,float64>`_
  393. ## * `tanh proc <#tanh,float64>`_
  394. ## * `arcsinh proc <#arcsinh,float64>`_
  395. ## * `sin proc <#sin,float64>`_
  396. ##
  397. ## .. code-block:: nim
  398. ## echo sinh(0.0) ## 0.0
  399. ## echo sinh(1.0) ## 1.175201193643801
  400. ## echo sinh(degToRad(90.0)) ## 2.301298902307295
  401. proc cosh*(x: float32): float32 {.importc: "coshf", header: "<math.h>".}
  402. proc cosh*(x: float64): float64 {.importc: "cosh", header: "<math.h>".}
  403. ## Computes the `hyperbolic cosine <https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions>`_ of ``x``.
  404. ##
  405. ## See also:
  406. ## * `sinh proc <#sinh,float64>`_
  407. ## * `tanh proc <#tanh,float64>`_
  408. ## * `arccosh proc <#arccosh,float64>`_
  409. ## * `cos proc <#cos,float64>`_
  410. ##
  411. ## .. code-block:: nim
  412. ## echo cosh(0.0) ## 1.0
  413. ## echo cosh(1.0) ## 1.543080634815244
  414. ## echo cosh(degToRad(90.0)) ## 2.509178478658057
  415. proc tanh*(x: float32): float32 {.importc: "tanhf", header: "<math.h>".}
  416. proc tanh*(x: float64): float64 {.importc: "tanh", header: "<math.h>".}
  417. ## Computes the `hyperbolic tangent <https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions>`_ of ``x``.
  418. ##
  419. ## See also:
  420. ## * `sinh proc <#sinh,float64>`_
  421. ## * `cosh proc <#cosh,float64>`_
  422. ## * `arctanh proc <#arctanh,float64>`_
  423. ## * `tan proc <#tan,float64>`_
  424. ##
  425. ## .. code-block:: nim
  426. ## echo tanh(0.0) ## 0.0
  427. ## echo tanh(1.0) ## 0.7615941559557649
  428. ## echo tanh(degToRad(90.0)) ## 0.9171523356672744
  429. proc arccos*(x: float32): float32 {.importc: "acosf", header: "<math.h>".}
  430. proc arccos*(x: float64): float64 {.importc: "acos", header: "<math.h>".}
  431. ## Computes the arc cosine of ``x``.
  432. ##
  433. ## See also:
  434. ## * `arcsin proc <#arcsin,float64>`_
  435. ## * `arctan proc <#arctan,float64>`_
  436. ## * `arctan2 proc <#arctan2,float64,float64>`_
  437. ## * `cos proc <#cos,float64>`_
  438. ##
  439. ## .. code-block:: nim
  440. ## echo radToDeg(arccos(0.0)) ## 90.0
  441. ## echo radToDeg(arccos(1.0)) ## 0.0
  442. proc arcsin*(x: float32): float32 {.importc: "asinf", header: "<math.h>".}
  443. proc arcsin*(x: float64): float64 {.importc: "asin", header: "<math.h>".}
  444. ## Computes the arc sine of ``x``.
  445. ##
  446. ## See also:
  447. ## * `arccos proc <#arccos,float64>`_
  448. ## * `arctan proc <#arctan,float64>`_
  449. ## * `arctan2 proc <#arctan2,float64,float64>`_
  450. ## * `sin proc <#sin,float64>`_
  451. ##
  452. ## .. code-block:: nim
  453. ## echo radToDeg(arcsin(0.0)) ## 0.0
  454. ## echo radToDeg(arcsin(1.0)) ## 90.0
  455. proc arctan*(x: float32): float32 {.importc: "atanf", header: "<math.h>".}
  456. proc arctan*(x: float64): float64 {.importc: "atan", header: "<math.h>".}
  457. ## Calculate the arc tangent of ``x``.
  458. ##
  459. ## See also:
  460. ## * `arcsin proc <#arcsin,float64>`_
  461. ## * `arccos proc <#arccos,float64>`_
  462. ## * `arctan2 proc <#arctan2,float64,float64>`_
  463. ## * `tan proc <#tan,float64>`_
  464. ##
  465. ## .. code-block:: nim
  466. ## echo arctan(1.0) ## 0.7853981633974483
  467. ## echo radToDeg(arctan(1.0)) ## 45.0
  468. proc arctan2*(y, x: float32): float32 {.importc: "atan2f",
  469. header: "<math.h>".}
  470. proc arctan2*(y, x: float64): float64 {.importc: "atan2", header: "<math.h>".}
  471. ## Calculate the arc tangent of ``y`` / ``x``.
  472. ##
  473. ## It produces correct results even when the resulting angle is near
  474. ## pi/2 or -pi/2 (``x`` near 0).
  475. ##
  476. ## See also:
  477. ## * `arcsin proc <#arcsin,float64>`_
  478. ## * `arccos proc <#arccos,float64>`_
  479. ## * `arctan proc <#arctan,float64>`_
  480. ## * `tan proc <#tan,float64>`_
  481. ##
  482. ## .. code-block:: nim
  483. ## echo arctan2(1.0, 0.0) ## 1.570796326794897
  484. ## echo radToDeg(arctan2(1.0, 0.0)) ## 90.0
  485. proc arcsinh*(x: float32): float32 {.importc: "asinhf", header: "<math.h>".}
  486. proc arcsinh*(x: float64): float64 {.importc: "asinh", header: "<math.h>".}
  487. ## Computes the inverse hyperbolic sine of ``x``.
  488. proc arccosh*(x: float32): float32 {.importc: "acoshf", header: "<math.h>".}
  489. proc arccosh*(x: float64): float64 {.importc: "acosh", header: "<math.h>".}
  490. ## Computes the inverse hyperbolic cosine of ``x``.
  491. proc arctanh*(x: float32): float32 {.importc: "atanhf", header: "<math.h>".}
  492. proc arctanh*(x: float64): float64 {.importc: "atanh", header: "<math.h>".}
  493. ## Computes the inverse hyperbolic tangent of ``x``.
  494. else: # JS
  495. proc log10*(x: float32): float32 {.importc: "Math.log10", nodecl.}
  496. proc log10*(x: float64): float64 {.importc: "Math.log10", nodecl.}
  497. proc log2*(x: float32): float32 {.importc: "Math.log2", nodecl.}
  498. proc log2*(x: float64): float64 {.importc: "Math.log2", nodecl.}
  499. proc exp*(x: float32): float32 {.importc: "Math.exp", nodecl.}
  500. proc exp*(x: float64): float64 {.importc: "Math.exp", nodecl.}
  501. proc sin*[T: float32|float64](x: T): T {.importc: "Math.sin", nodecl.}
  502. proc cos*[T: float32|float64](x: T): T {.importc: "Math.cos", nodecl.}
  503. proc tan*[T: float32|float64](x: T): T {.importc: "Math.tan", nodecl.}
  504. proc sinh*[T: float32|float64](x: T): T {.importc: "Math.sinh", nodecl.}
  505. proc cosh*[T: float32|float64](x: T): T {.importc: "Math.cosh", nodecl.}
  506. proc tanh*[T: float32|float64](x: T): T {.importc: "Math.tanh", nodecl.}
  507. proc arcsin*[T: float32|float64](x: T): T {.importc: "Math.asin", nodecl.}
  508. proc arccos*[T: float32|float64](x: T): T {.importc: "Math.acos", nodecl.}
  509. proc arctan*[T: float32|float64](x: T): T {.importc: "Math.atan", nodecl.}
  510. proc arctan2*[T: float32|float64](y, x: T): T {.importc: "Math.atan2", nodecl.}
  511. proc arcsinh*[T: float32|float64](x: T): T {.importc: "Math.asinh", nodecl.}
  512. proc arccosh*[T: float32|float64](x: T): T {.importc: "Math.acosh", nodecl.}
  513. proc arctanh*[T: float32|float64](x: T): T {.importc: "Math.atanh", nodecl.}
  514. proc cot*[T: float32|float64](x: T): T = 1.0 / tan(x)
  515. ## Computes the cotangent of ``x`` (1 / tan(x)).
  516. proc sec*[T: float32|float64](x: T): T = 1.0 / cos(x)
  517. ## Computes the secant of ``x`` (1 / cos(x)).
  518. proc csc*[T: float32|float64](x: T): T = 1.0 / sin(x)
  519. ## Computes the cosecant of ``x`` (1 / sin(x)).
  520. proc coth*[T: float32|float64](x: T): T = 1.0 / tanh(x)
  521. ## Computes the hyperbolic cotangent of ``x`` (1 / tanh(x)).
  522. proc sech*[T: float32|float64](x: T): T = 1.0 / cosh(x)
  523. ## Computes the hyperbolic secant of ``x`` (1 / cosh(x)).
  524. proc csch*[T: float32|float64](x: T): T = 1.0 / sinh(x)
  525. ## Computes the hyperbolic cosecant of ``x`` (1 / sinh(x)).
  526. proc arccot*[T: float32|float64](x: T): T = arctan(1.0 / x)
  527. ## Computes the inverse cotangent of ``x``.
  528. proc arcsec*[T: float32|float64](x: T): T = arccos(1.0 / x)
  529. ## Computes the inverse secant of ``x``.
  530. proc arccsc*[T: float32|float64](x: T): T = arcsin(1.0 / x)
  531. ## Computes the inverse cosecant of ``x``.
  532. proc arccoth*[T: float32|float64](x: T): T = arctanh(1.0 / x)
  533. ## Computes the inverse hyperbolic cotangent of ``x``.
  534. proc arcsech*[T: float32|float64](x: T): T = arccosh(1.0 / x)
  535. ## Computes the inverse hyperbolic secant of ``x``.
  536. proc arccsch*[T: float32|float64](x: T): T = arcsinh(1.0 / x)
  537. ## Computes the inverse hyperbolic cosecant of ``x``.
  538. const windowsCC89 = defined(windows) and defined(bcc)
  539. when not defined(js): # C
  540. proc hypot*(x, y: float32): float32 {.importc: "hypotf", header: "<math.h>".}
  541. proc hypot*(x, y: float64): float64 {.importc: "hypot", header: "<math.h>".}
  542. ## Computes the hypotenuse of a right-angle triangle with ``x`` and
  543. ## ``y`` as its base and height. Equivalent to ``sqrt(x*x + y*y)``.
  544. ##
  545. ## .. code-block:: nim
  546. ## echo hypot(4.0, 3.0) ## 5.0
  547. proc pow*(x, y: float32): float32 {.importc: "powf", header: "<math.h>".}
  548. proc pow*(x, y: float64): float64 {.importc: "pow", header: "<math.h>".}
  549. ## Computes x to power raised of y.
  550. ##
  551. ## To compute power between integers (e.g. 2^6), use `^ proc<#^,T,Natural>`_.
  552. ##
  553. ## See also:
  554. ## * `^ proc<#^,T,Natural>`_
  555. ## * `sqrt proc <#sqrt,float64>`_
  556. ## * `cbrt proc <#cbrt,float64>`_
  557. ##
  558. ## .. code-block:: nim
  559. ## echo pow(100, 1.5) ## 1000.0
  560. ## echo pow(16.0, 0.5) ## 4.0
  561. # TODO: add C89 version on windows
  562. when not windowsCC89:
  563. proc erf*(x: float32): float32 {.importc: "erff", header: "<math.h>".}
  564. proc erf*(x: float64): float64 {.importc: "erf", header: "<math.h>".}
  565. ## Computes the `error function <https://en.wikipedia.org/wiki/Error_function>`_ for ``x``.
  566. ##
  567. ## Note: Not available for JS backend.
  568. proc erfc*(x: float32): float32 {.importc: "erfcf", header: "<math.h>".}
  569. proc erfc*(x: float64): float64 {.importc: "erfc", header: "<math.h>".}
  570. ## Computes the `complementary error function <https://en.wikipedia.org/wiki/Error_function#Complementary_error_function>`_ for ``x``.
  571. ##
  572. ## Note: Not available for JS backend.
  573. proc gamma*(x: float32): float32 {.importc: "tgammaf", header: "<math.h>".}
  574. proc gamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".}
  575. ## Computes the the `gamma function <https://en.wikipedia.org/wiki/Gamma_function>`_ for ``x``.
  576. ##
  577. ## Note: Not available for JS backend.
  578. ##
  579. ## See also:
  580. ## * `lgamma proc <#lgamma,float64>`_ for a natural log of gamma function
  581. ##
  582. ## .. code-block:: Nim
  583. ## echo gamma(1.0) # 1.0
  584. ## echo gamma(4.0) # 6.0
  585. ## echo gamma(11.0) # 3628800.0
  586. ## echo gamma(-1.0) # nan
  587. proc lgamma*(x: float32): float32 {.importc: "lgammaf", header: "<math.h>".}
  588. proc lgamma*(x: float64): float64 {.importc: "lgamma", header: "<math.h>".}
  589. ## Computes the natural log of the gamma function for ``x``.
  590. ##
  591. ## Note: Not available for JS backend.
  592. ##
  593. ## See also:
  594. ## * `gamma proc <#gamma,float64>`_ for gamma function
  595. ##
  596. ## .. code-block:: Nim
  597. ## echo lgamma(1.0) # 1.0
  598. ## echo lgamma(4.0) # 1.791759469228055
  599. ## echo lgamma(11.0) # 15.10441257307552
  600. ## echo lgamma(-1.0) # inf
  601. proc floor*(x: float32): float32 {.importc: "floorf", header: "<math.h>".}
  602. proc floor*(x: float64): float64 {.importc: "floor", header: "<math.h>".}
  603. ## Computes the floor function (i.e., the largest integer not greater than ``x``).
  604. ##
  605. ## See also:
  606. ## * `ceil proc <#ceil,float64>`_
  607. ## * `round proc <#round,float64>`_
  608. ## * `trunc proc <#trunc,float64>`_
  609. ##
  610. ## .. code-block:: nim
  611. ## echo floor(2.1) ## 2.0
  612. ## echo floor(2.9) ## 2.0
  613. ## echo floor(-3.5) ## -4.0
  614. proc ceil*(x: float32): float32 {.importc: "ceilf", header: "<math.h>".}
  615. proc ceil*(x: float64): float64 {.importc: "ceil", header: "<math.h>".}
  616. ## Computes the ceiling function (i.e., the smallest integer not smaller
  617. ## than ``x``).
  618. ##
  619. ## See also:
  620. ## * `floor proc <#floor,float64>`_
  621. ## * `round proc <#round,float64>`_
  622. ## * `trunc proc <#trunc,float64>`_
  623. ##
  624. ## .. code-block:: nim
  625. ## echo ceil(2.1) ## 3.0
  626. ## echo ceil(2.9) ## 3.0
  627. ## echo ceil(-2.1) ## -2.0
  628. when windowsCC89:
  629. # MSVC 2010 don't have trunc/truncf
  630. # this implementation was inspired by Go-lang Math.Trunc
  631. proc truncImpl(f: float64): float64 =
  632. const
  633. mask: uint64 = 0x7FF
  634. shift: uint64 = 64 - 12
  635. bias: uint64 = 0x3FF
  636. if f < 1:
  637. if f < 0: return -truncImpl(-f)
  638. elif f == 0: return f # Return -0 when f == -0
  639. else: return 0
  640. var x = cast[uint64](f)
  641. let e = (x shr shift) and mask - bias
  642. # Keep the top 12+e bits, the integer part; clear the rest.
  643. if e < 64-12:
  644. x = x and (not (1'u64 shl (64'u64-12'u64-e) - 1'u64))
  645. result = cast[float64](x)
  646. proc truncImpl(f: float32): float32 =
  647. const
  648. mask: uint32 = 0xFF
  649. shift: uint32 = 32 - 9
  650. bias: uint32 = 0x7F
  651. if f < 1:
  652. if f < 0: return -truncImpl(-f)
  653. elif f == 0: return f # Return -0 when f == -0
  654. else: return 0
  655. var x = cast[uint32](f)
  656. let e = (x shr shift) and mask - bias
  657. # Keep the top 9+e bits, the integer part; clear the rest.
  658. if e < 32-9:
  659. x = x and (not (1'u32 shl (32'u32-9'u32-e) - 1'u32))
  660. result = cast[float32](x)
  661. proc trunc*(x: float64): float64 =
  662. if classify(x) in {fcZero, fcNegZero, fcNan, fcInf, fcNegInf}: return x
  663. result = truncImpl(x)
  664. proc trunc*(x: float32): float32 =
  665. if classify(x) in {fcZero, fcNegZero, fcNan, fcInf, fcNegInf}: return x
  666. result = truncImpl(x)
  667. proc round*[T: float32|float64](x: T): T =
  668. ## Windows compilers prior to MSVC 2012 do not implement 'round',
  669. ## 'roundl' or 'roundf'.
  670. result = if x < 0.0: ceil(x - T(0.5)) else: floor(x + T(0.5))
  671. else:
  672. proc round*(x: float32): float32 {.importc: "roundf", header: "<math.h>".}
  673. proc round*(x: float64): float64 {.importc: "round", header: "<math.h>".}
  674. ## Rounds a float to zero decimal places.
  675. ##
  676. ## Used internally by the `round proc <#round,T,int>`_
  677. ## when the specified number of places is 0.
  678. ##
  679. ## See also:
  680. ## * `round proc <#round,T,int>`_ for rounding to the specific
  681. ## number of decimal places
  682. ## * `floor proc <#floor,float64>`_
  683. ## * `ceil proc <#ceil,float64>`_
  684. ## * `trunc proc <#trunc,float64>`_
  685. ##
  686. ## .. code-block:: nim
  687. ## echo round(3.4) ## 3.0
  688. ## echo round(3.5) ## 4.0
  689. ## echo round(4.5) ## 5.0
  690. proc trunc*(x: float32): float32 {.importc: "truncf", header: "<math.h>".}
  691. proc trunc*(x: float64): float64 {.importc: "trunc", header: "<math.h>".}
  692. ## Truncates ``x`` to the decimal point.
  693. ##
  694. ## See also:
  695. ## * `floor proc <#floor,float64>`_
  696. ## * `ceil proc <#ceil,float64>`_
  697. ## * `round proc <#round,float64>`_
  698. ##
  699. ## .. code-block:: nim
  700. ## echo trunc(PI) # 3.0
  701. ## echo trunc(-1.85) # -1.0
  702. proc `mod`*(x, y: float32): float32 {.importc: "fmodf", header: "<math.h>".}
  703. proc `mod`*(x, y: float64): float64 {.importc: "fmod", header: "<math.h>".}
  704. ## Computes the modulo operation for float values (the remainder of ``x`` divided by ``y``).
  705. ##
  706. ## See also:
  707. ## * `floorMod proc <#floorMod,T,T>`_ for Python-like (% operator) behavior
  708. ##
  709. ## .. code-block:: nim
  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. ## (-6.5 mod -2.5) == -1.5
  714. else: # JS
  715. proc hypot*(x, y: float32): float32 {.importc: "Math.hypot", varargs, nodecl.}
  716. proc hypot*(x, y: float64): float64 {.importc: "Math.hypot", varargs, nodecl.}
  717. proc pow*(x, y: float32): float32 {.importc: "Math.pow", nodecl.}
  718. proc pow*(x, y: float64): float64 {.importc: "Math.pow", nodecl.}
  719. proc floor*(x: float32): float32 {.importc: "Math.floor", nodecl.}
  720. proc floor*(x: float64): float64 {.importc: "Math.floor", nodecl.}
  721. proc ceil*(x: float32): float32 {.importc: "Math.ceil", nodecl.}
  722. proc ceil*(x: float64): float64 {.importc: "Math.ceil", nodecl.}
  723. proc round*(x: float): float {.importc: "Math.round", nodecl.}
  724. proc trunc*(x: float32): float32 {.importc: "Math.trunc", nodecl.}
  725. proc trunc*(x: float64): float64 {.importc: "Math.trunc", nodecl.}
  726. proc `mod`*(x, y: float32): float32 {.importcpp: "# % #".}
  727. proc `mod`*(x, y: float64): float64 {.importcpp: "# % #".}
  728. ## Computes the modulo operation for float values (the remainder of ``x`` divided by ``y``).
  729. ##
  730. ## .. code-block:: nim
  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. ## (-6.5 mod -2.5) == -1.5
  735. proc round*[T: float32|float64](x: T, places: int): T =
  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. runnableExamples:
  804. var x: int
  805. doAssert frexp(5.0, x) == 0.625
  806. doAssert 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. runnableExamples:
  866. doAssert splitDecimal(5.25) == (intpart: 5.0, floatpart: 0.25)
  867. doAssert 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. runnableExamples:
  884. doAssert 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. runnableExamples:
  893. doAssert radToDeg(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. runnableExamples:
  904. doAssert sgn(5) == 1
  905. doAssert sgn(0) == 0
  906. doAssert sgn(-4.1) == -1
  907. ord(T(0) < x) - ord(x < T(0))
  908. {.pop.}
  909. {.pop.}
  910. proc `^`*[T: SomeNumber](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(lgamma(1.0) == 0.0) # ln(1.0) == 0.0
  1030. assert(erf(6.0) > erf(5.0))
  1031. assert(erfc(6.0) < erfc(5.0))
  1032. when isMainModule:
  1033. # Function for approximate comparison of floats
  1034. proc `==~`(x, y: float): bool = (abs(x-y) < 1e-9)
  1035. block: # prod
  1036. doAssert prod([1, 2, 3, 4]) == 24
  1037. doAssert prod([1.5, 3.4]) == 5.1
  1038. let x: seq[float] = @[]
  1039. doAssert prod(x) == 1.0
  1040. block: # round() tests
  1041. # Round to 0 decimal places
  1042. doAssert round(54.652) ==~ 55.0
  1043. doAssert round(54.352) ==~ 54.0
  1044. doAssert round(-54.652) ==~ -55.0
  1045. doAssert round(-54.352) ==~ -54.0
  1046. doAssert round(0.0) ==~ 0.0
  1047. block: # splitDecimal() tests
  1048. doAssert splitDecimal(54.674).intpart ==~ 54.0
  1049. doAssert splitDecimal(54.674).floatpart ==~ 0.674
  1050. doAssert splitDecimal(-693.4356).intpart ==~ -693.0
  1051. doAssert splitDecimal(-693.4356).floatpart ==~ -0.4356
  1052. doAssert splitDecimal(0.0).intpart ==~ 0.0
  1053. doAssert splitDecimal(0.0).floatpart ==~ 0.0
  1054. block: # trunc tests for vcc
  1055. doAssert(trunc(-1.1) == -1)
  1056. doAssert(trunc(1.1) == 1)
  1057. doAssert(trunc(-0.1) == -0)
  1058. doAssert(trunc(0.1) == 0)
  1059. #special case
  1060. doAssert(classify(trunc(1e1000000)) == fcInf)
  1061. doAssert(classify(trunc(-1e1000000)) == fcNegInf)
  1062. doAssert(classify(trunc(0.0/0.0)) == fcNan)
  1063. doAssert(classify(trunc(0.0)) == fcZero)
  1064. #trick the compiler to produce signed zero
  1065. let
  1066. f_neg_one = -1.0
  1067. f_zero = 0.0
  1068. f_nan = f_zero / f_zero
  1069. doAssert(classify(trunc(f_neg_one*f_zero)) == fcNegZero)
  1070. doAssert(trunc(-1.1'f32) == -1)
  1071. doAssert(trunc(1.1'f32) == 1)
  1072. doAssert(trunc(-0.1'f32) == -0)
  1073. doAssert(trunc(0.1'f32) == 0)
  1074. doAssert(classify(trunc(1e1000000'f32)) == fcInf)
  1075. doAssert(classify(trunc(-1e1000000'f32)) == fcNegInf)
  1076. doAssert(classify(trunc(f_nan.float32)) == fcNan)
  1077. doAssert(classify(trunc(0.0'f32)) == fcZero)
  1078. block: # sgn() tests
  1079. assert sgn(1'i8) == 1
  1080. assert sgn(1'i16) == 1
  1081. assert sgn(1'i32) == 1
  1082. assert sgn(1'i64) == 1
  1083. assert sgn(1'u8) == 1
  1084. assert sgn(1'u16) == 1
  1085. assert sgn(1'u32) == 1
  1086. assert sgn(1'u64) == 1
  1087. assert sgn(-12342.8844'f32) == -1
  1088. assert sgn(123.9834'f64) == 1
  1089. assert sgn(0'i32) == 0
  1090. assert sgn(0'f32) == 0
  1091. assert sgn(NegInf) == -1
  1092. assert sgn(Inf) == 1
  1093. assert sgn(NaN) == 0
  1094. block: # fac() tests
  1095. try:
  1096. discard fac(-1)
  1097. except AssertionDefect:
  1098. discard
  1099. doAssert fac(0) == 1
  1100. doAssert fac(1) == 1
  1101. doAssert fac(2) == 2
  1102. doAssert fac(3) == 6
  1103. doAssert fac(4) == 24
  1104. block: # floorMod/floorDiv
  1105. doAssert floorDiv(8, 3) == 2
  1106. doAssert floorMod(8, 3) == 2
  1107. doAssert floorDiv(8, -3) == -3
  1108. doAssert floorMod(8, -3) == -1
  1109. doAssert floorDiv(-8, 3) == -3
  1110. doAssert floorMod(-8, 3) == 1
  1111. doAssert floorDiv(-8, -3) == 2
  1112. doAssert floorMod(-8, -3) == -2
  1113. doAssert floorMod(8.0, -3.0) ==~ -1.0
  1114. doAssert floorMod(-8.5, 3.0) ==~ 0.5
  1115. block: # log
  1116. doAssert log(4.0, 3.0) ==~ ln(4.0) / ln(3.0)
  1117. doAssert log2(8.0'f64) == 3.0'f64
  1118. doAssert log2(4.0'f64) == 2.0'f64
  1119. doAssert log2(2.0'f64) == 1.0'f64
  1120. doAssert log2(1.0'f64) == 0.0'f64
  1121. doAssert classify(log2(0.0'f64)) == fcNegInf
  1122. doAssert log2(8.0'f32) == 3.0'f32
  1123. doAssert log2(4.0'f32) == 2.0'f32
  1124. doAssert log2(2.0'f32) == 1.0'f32
  1125. doAssert log2(1.0'f32) == 0.0'f32
  1126. doAssert classify(log2(0.0'f32)) == fcNegInf