Search code examples
clojureprecisionbigdecimal

Clojure - How to set the lower precision


I know that to set the precision for numbers in Clojure I should use with-precision function and I know that it works only with BigDecimal values.

(defn bar-triang [[a b] [c d] [e f]]
  (def cen [(/ (+ a c) 2.0) (/ (+ b d) 2.0)])
  (def g (get cen 0))
  (def h (get cen 1))
    [(with-precision 4 (+ (bigdec g) (/ (- e g) 3M)))
     (with-precision 4 (+ (bigdec h) (/ (- f h) 3M)))])

(bar-triang [4, 6], [12, 4], [10, 10])
=> [8.666666666666666 6.666666666666667]

Here, I've set the precision to 4, but REPL gives me the same number as before with more digits. Furthermore, I've coerced g and h to BigDecimal using bigdec, but problem remains the same. How can I solve this problem?


Solution

  • a bit of refactoring later:

    1. using let instead of def
    2. why produce cen vector when you only need h and g
    3. using _M for the numeric literals
    4. wrap the whole thing in with-precision 4
    5. drop bigdec coercions (thx /u/glts)
    6. this may not be the best variant but to my knowledge it produces you desired output
    7. It might be a good time to apply/research automated testing with clojure

    (defn bar-triang [[a b] [c d] [e f]]
      (with-precision 4
        (let [g (/ (+ a c) 2M)
              h (/ (+ b d) 2M)]
          [(+ g (/ (- e g) 3M))
           (+ h (/ (- f h) 3M))])))
    #'user/bar-triang
    user=> (bar-triang [4, 6], [12, 4], [10, 10])
    [8.667M 6.667M]