1
votes

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?

1
not regarding precision, but to declare local variable use let like (let [a 3] ..) - you effectevly declare cen g and h as global accessible vars - birdspider

1 Answers

2
votes

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]