In clojure or jython: say I have a number 4.21312312312312 how can i get a number with just the first 2 decimals. It would return 4.21 for the example above. Thanks
-
1See especially the first answer here: http://stackoverflow.com/questions/153724/how-to-round-a-number-to-n-decimal-places-in-java – G__ Feb 22 '11 at 00:01
5 Answers
Clojure has a round function in clojure.contrib.math - it's probably best to use this one assuming you want correct behaviour with all the different possible numerical types that Clojure can handle.
In which case, and assuming you want the result as an arbitrary-precision BigDecimal, an easy approach is to build a little helper function as follows:
(use 'clojure.contrib.math)
(defn round-places [number decimals]
(let [factor (expt 10 decimals)]
(bigdec (/ (round (* factor number)) factor))))
(round-places 4.21312312312312 2)
=> 4.21M

- 105,238
- 25
- 256
- 415
-
1I am new to Clojure, may I ask how to install contributed library for Clojure? When I run your code, I got this: user=> (use 'clojure.contrib.math) FileNotFoundException Could not locate clojure/contrib/math__init.class or clojure/contrib/math.clj on classpath: cloj ure.lang.RT.load (RT.java:443) user=> Thank you! – Nick May 13 '14 at 03:06
-
For those with Nick's question, clojure.contrib.math is now clojure.math.numeric-tower. If you use Leiningen, you'll need to include this in the dependencies: `[org.clojure/math.numeric-tower "0.0.4"]`, or the same thing with some later version number. – Mars Jun 30 '16 at 15:02
-
My version ```(defn round-places [number decimals] (let [factor (Math/pow 10 decimals)] (double (/ (Math/round (* factor number)) factor))))``` which uses java.lang.math – Phil Huhn Dec 06 '19 at 14:10
I think I got this one after further research
(format "%.2f" 4.21312312312312)
should return 4.21

- 9,067
- 19
- 55
- 70
-
7This is the string representation of the number, not the number itself. – Miki Tebeka Feb 22 '11 at 17:32
Multiply by 10^numberofdecimals
you want, round, and then divide. This doesn't guarantee the string representation will be rounded correctly, but should work most of the time. For example:
(* 0.01 (Math/round (* 100 (float (/ 7 8)))))
Yielding 0.88

- 296,393
- 112
- 651
- 745
Taking it one step further, you could parametize the number of decimal places:
(defn- factor [no-of-decimal-places]
(.pow (BigInteger. "10") no-of-decimal-places))
(defn truncate [value decimal-places]
(let [divide-and-multiply-by (factor decimal-places)]
(float (/ (int (* divide-and-multiply-by value)) divide-and-multiply-by))))
(truncate 2.23999999 2)
=> 2.23
(truncate 2.23999999 3)
=> 2.239
(truncate 2.23999999 4)
=> 2.2399

- 11
- 1
Found this thread looking for a similar truncation answer.
Not sure if there is a better solution, but came up with the following.
For non-rounding, you can multiple by 100 (for 2 decimal places, 1000 for 3 etc), turn into an integer and then divide by the original factor, before converting to a float for numeric output. For example:
(float (/ (int (* 100 123.1299)) 100))
=> 123.12
(float (/ (int (* 100 123.1209)) 100))
=> 123.12

- 11
- 1