如何将数字字符串转换为数字(十进制),以及将数字转换为字符串

19

我该如何编写一个将十进制数字符串转换为十进制数和将十进制数转换为字符串的函数?

4个回答

43

有非常方便的Clojure函数,可以将任何类型转换为字符串,并将类似数字的内容转换为BigDecimal:

user=> (bigdec "1234")
1234M
user=> (str 1234M)
"1234"
我想这是Clojure的规范方式。

5
这个例子将数字字符串转换为数字。
(defn String->Number [str]
  (let [n (read-string str)]
       (if (number? n) n nil)))

样例:

user=> (String->Number "4.5")
4.5
user=> (str 4.5)
"4.5"
user=> (String->Number "abc")
nil

13
在实际生活中,你可能不应该使用这个。从文档来看,它可以执行任意代码https://clojuredocs.org/clojure.core/read-string,这是一个巨大的安全漏洞。我认为`bigdec`是更好的解决方案。 - Matt Luongo

2
请注意,read-string返回的是浮点数,而不是十进制数:
user=> (.getClass (read-string "1.01"))
java.lang.Double

你获得的数字打印出来看起来像你所期望的,但实际上并不完全相同。
user=> (new BigDecimal (read-string "1.01"))
1.0100000000000000088817841970012523233890533447265625M

您可以使用java.math.BigDecimal代替浮点数,避免浮点数计算时的问题。
user=> (new BigDecimal "1.01")
1.01M
user=> (.toString (new BigDecimal "1.01"))
"1.01"

1
从您的问题来看,您似乎想要一个切换功能,即可以读取数字并转换为字符串,也可以读取字符串并返回数字,如果该字符串包含数字,例如123.0或“123.0”。
以下是一个示例:
(defn cvt-str-num [val]
    (if (try 
            (number? val)
            (catch Exception e (str "Invalid number: " (.getMessage e))))
        (str val)
        (let [n-val (read-string val)]
            (if (number? n-val)
                n-val
                nil))))

我看不出有绕过n-val的let绑定的方法,因为需要一个中间位置来存储read-string返回值,以便将其作为数字进行测试。如果它是一个数字,则返回该数字;否则返回nil。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接