kamituel
kamituel

Reputation: 35960

No decimal places with cl-format (lisp format)

I want to create a function that will format a number with exactly as many decimal places as I want. Here's my attempt with cl-format:

=> (defn f [decimal-places n] (clojure.pprint/cl-format nil (str "~" decimal-places ",0$") n))
#'core/f
=> (f 5 55)
"55.00000"
=> (f 4 55)
"55.0000"
=> (f 3 55)
"55.000"
=> (f 2 55)
"55.00"
=> (f 1 55)
"55.0"
=> (f 0 55)
"55."

Notice the last one, with zero decimal places. I'm doing essentially this:

=> (clojure.pprint/cl-format nil "~0,0$" 55)
"55."

It has decimal separator - a dot - in there. How do make it render simply "55" (without a dot), in a way that I could easily (like with str in my example) make it to work with decimal-places greater than 0?

Upvotes: 2

Views: 478

Answers (1)

coredump
coredump

Reputation: 38924

Although cl-format supports branching, in this case I'd stick with a simple if, because the arguments of format actually are quite different in both cases:

(defn f [decimal-places n]
  (if (zero? decimal-places)
      (clojure.pprint/cl-format nil "~D" (Math/round n))
      (clojure.pprint/cl-format nil "~v$" decimal-places n)))

I round n to the nearest integer instead of just truncating with (int n).

An alternative is to remove any dot character at the end of the formatted string:

(defn undot [string]
  (if (clojure.string/ends-with? string ".")
      (subs string 0 (- (count string) 1))
      string))

(defn f [decimal-places n]
  (undot (clojure.pprint/cl-format nil "~v$" decimal-places n)))

Upvotes: 3

Related Questions