1

How do I determine the count of digits after the decimal point.

[ 1.6712 2.053 3.52 ]
;;1.6712 => 4
;;2.053 => 3
;;3.52 => 2
Ezekiel
  • 167
  • 3
  • 11
  • 2
    There is no such thing as "the count of digits after the decimal number." You mean the decimals in the string representation of the number? In that case, 2.050 is 2.05 so it has two decimals. What are you trying to do exactly and why is the number of decimals important? – Diego Basch Aug 03 '15 at 16:59
  • To detect a number that has more than 5 number of decimals – Ezekiel Aug 03 '15 at 17:06
  • 1
    What is the underlying problem? Keep in mind that the number of digits does not equate to the precision of a value (e.g. 1.2500 = 1.25 = 5/4 is more precise than 1.3333 (4/3) even though 1.25 needs only 2 decimal places. – Alan Thompson Aug 03 '15 at 17:17

2 Answers2

2

Keep in mind: What Every Computer Scientist Should Know About Floating-Point Arithmetic

So a trivial/mathematical attempt could be.

But this will not work for every double!

(defn more-than-5 [number]
   (let [n (* number 10E4)]
     (pos? (- n (int n)))))

This approach should work:

(defn primefactors
  ([n]
   (primefactors n 2 '()))
  ([n candidate acc]
   (cond (<= n 1) (reverse acc)
     (zero? (rem n candidate)) (recur (/ n candidate) candidate (cons candidate acc))
     :else (recur n (inc candidate) acc))))

primefactors function from https://stackoverflow.com/a/9556744

(defn length-of-period [n]
  (if (integer? n)
      [0 0]
      (let [groups (->> n
                        rationalize
                        denominator
                        primefactors
                        (group-by #(zero? (mod 10 %))))
            b1 (apply * (get groups true))
            b2 (apply * (get groups false))]
       [(count (take-while
                  #(pos? (mod % b1))
                  (take 20 (iterate #(bigint (* 10 %)) 1))))
        (count (take-while
                  #(pos? (mod % b2))
                  (take 20 (iterate #(bigint (- (* 10 %) 1)) 1))))])))

The result is a vector [length-of-preperiod length-of-period] Example:

(length-of-period 0.123456) => [6 0]
(length-of-period 1/3) => [0 1]
;; 1/3 = 0.3333...
(length-of-period 7/12) => [2 1]
;; 7/12 = 0.583333....

So in case of doubles you can filter your numbers with #(> 6 (first (length-of-period %)))

Community
  • 1
  • 1
user5187212
  • 426
  • 2
  • 7
0

From: Number of decimal digits in a double

A double is not always an exact representation. You can only say how many decimal places you would have if you converted it to a String.

Community
  • 1
  • 1
Daniel Compton
  • 13,878
  • 4
  • 40
  • 60