我有代表十进制值的字符串,例如:“0.010”,“0.0100000”“00.01000”
我想将它们舍入到指定的格式,例如:#。##
在Java中我们有:
public BigDecimal setScale(int newScale, RoundingMode roundingMode) {
return setScale(newScale, roundingMode.oldMode);
}
在Clojure中实现这一目标的最佳方法是什么,而不是使用互操作?
你可以使用Clojure的format
来达到这个目的。它应该为您提供问题的解决方案。以下是一些示例和参考:
user=> (format "%.2f" 0.010)
"0.01"
user=> (format "%.2f" 0.010000)
"0.01"
user=> (format "%.2f" 00.010000000)
user=> (doc format)
-------------------------
clojure.core/format
([fmt & args])
Formats a string using java.lang.String.format, see java.util.Formatter for format
string syntax
这是clojure-doc.org上一个示例的略微修改版本:
(defn round2
"Round a double to the given precision (number of significant digits)"
[precision d]
(let [factor (Math/pow 10 precision)]
(/ (Math/round (* d factor)) factor)))
对于很多情况,@ number23_cn的答案是正确的。但是,例如,如果要显示每个舍入数字的序列,则具有精度参数的实际舍入函数可能很有用。然后你可以简单地在序列上映射round2
,一次格式化每个数字:
(map (partial round2 2) [0.001 10.123456 9.5556])
返回
(0.0 10.12 9.56)
当然,这对更长的序列更有用。
另一个选择是使用cl-format
,它是Common Lisp的format
的Clojure实现。它类似于Clojure的format
(基于java.util.Formatter
)但具有不同的语法,并允许一些更高级的技巧。
(clojure.pprint/cl-format nil "~,2f" 23.456)
; => "23.46"
~{ ~}
指令允许处理序列,如上面的第一个示例所示:
(clojure.pprint/cl-format nil "~{ ~,2f~}" [0.001 10.123456 9.5556])
; => " 0.00 10.12 9.56"
~{ ~}
希望看到一个序列作为参数,并将使用~{
和~}
之间出现的任何指令逐个吃掉序列的元素。
(来自Peter Seibel的chapter on format
的Practical Common Lisp是对Common Lisp的format
的最好的介绍,因此对Clojure的cl-format
,imo。通常来源的documentation on CL's format
,Common Lisp Hyperspec,有时很难使用.section on CL's format
中的Common Lisp The Language稍好一些。)
接受的答案推荐format
,但format
没有回合(正如其中一条评论所指出的那样)。另一个答案(火星)不适用于BigDecimal
s。要将bigdec
s舍入到Clojure中的多个小数位,我找到的唯一解决方案是使用Java互操作:
(defn round [s]
(fn [n]
(assert (bigdec? n))
(.setScale n s RoundingMode/HALF_EVEN)))
(def round4 (round 4))
在十进制数字上使用Double/ParseDouble
后使用函数format
将返回一个小数四舍五入到使用format
描述的所需小数位数。像这样:
user=> (Double/parseDouble (format "%.2f" 0.009) )
0.01
如果进一步计算需要舍入数字,则解析Double非常重要。但是,如果只需要输出舍入数字,则使用format
是合适的。