summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/math.nim25
-rw-r--r--web/news.txt2
2 files changed, 27 insertions, 0 deletions
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index bd6764433..1edbfcab6 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -312,6 +312,23 @@ else:
       exponent = round(ex)
       result = x / pow(2.0, ex)
 
+proc splitDecimal*[T: float32|float64](x: T): tuple[intpart: T, floatpart: T] =
+  ## Breaks `x` into an integral and a fractional part.
+  ##
+  ## Returns a tuple containing intpart and floatpart representing
+  ## the integer part and the fractional part respectively.
+  ##
+  ## Both parts have the same sign as `x`.  Analogous to the `modf`
+  ## function in C.
+  var
+    absolute: T
+  absolute = abs(x)
+  result.intpart = floor(absolute)
+  result.floatpart = absolute - result.intpart
+  if x < 0:
+    result.intpart = -result.intpart
+    result.floatpart = -result.floatpart
+
 {.pop.}
 
 proc degToRad*[T: float32|float64](d: T): T {.inline.} =
@@ -399,3 +416,11 @@ when isMainModule:
     doAssert floatIsEqual(round(-547.652, -2), -500.0)
     doAssert floatIsEqual(round(-547.652, -3), -1000.0)
     doAssert floatIsEqual(round(-547.652, -4), 0.0)
+
+  block: # splitDecimal() tests
+    doAssert floatIsEqual(splitDecimal(54.674).intpart, 54.0)
+    doAssert floatIsEqual(splitDecimal(54.674).floatpart, 0.674)
+    doAssert floatIsEqual(splitDecimal(-693.4356).intpart, -693.0)
+    doAssert floatIsEqual(splitDecimal(-693.4356).floatpart, -0.4356)
+    doAssert floatIsEqual(splitDecimal(0.0).intpart, 0.0)
+    doAssert floatIsEqual(splitDecimal(0.0).floatpart, 0.0)
diff --git a/web/news.txt b/web/news.txt
index 3dd6c4e1e..3290baa5c 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -61,6 +61,8 @@ Library Additions
 - Added ``strscans`` module that implements a ``scanf`` for easy input extraction.
 - Added a version of ``parseutils.parseUntil`` that can deal with a string ``until`` token. The other
   versions are for ``char`` and ``set[char]``.
+- Added ``splitDecimal`` to ``math.nim`` to split a floating point value
+  into an integer part and a floating part (in the range -1<x<1).
 
 
 Compiler Additions