parsing - 在 ClojureScript 程序中使用 Cuerdas 解析十进制数
问题描述
我在 ClojureScript 程序中使用Cuerdas 库来解析浮点数。有时来自用户的输入缺少不可或缺的部分,例如.1
for 0.1
。我需要处理这个。但是在比较解析的数字时,我遇到了奇怪的结果:
(= 0.1 (parse-number "0.1"))
;; => true
(= .1 (parse-number "0.1"))
;; => true
(= 0.1 (parse-number ".1"))
;; => false
(= .1 (parse-number ".1"))
;; => false
上面的最后两个结果让我感到惊讶。比较文字数字时,我得到了预期的结果:
(= 0 .0)
;; => true
当我只解析没有整数部分的十进制数时,也可以看到奇怪的行为,如下所示:
(parse-number ".1")
;; => .1
.1
;; => 0.1
我发现我可以用它js/parseFloat
来获得我想要的东西,但我很好奇在使用 Cuerdas 时这种行为的原因是什么?这个.1
值是多少,它与 有何不同0.1
?
解决方案
parse-number
源看起来像这样:
(defn parse-number
"General purpose function for parse number like
string to number. It works with both integers
and floats."
[s]
(if (nil? s)
#?(:cljs js/NaN :clj Double/NaN)
(if (numeric? s)
(edn/read-string s)
#?(:cljs js/NaN :clj Double/NaN))))
两者".1"
和"0.1"
都被认为是numeric?
(通过正则表达式检查在 cuerdas 中实现):
cljs.user=> (def re #"^[+-]?([0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*)([eE][+-]?[0-9]+)?$")
#'cljs.user/re
cljs.user=> (boolean (re-matches re "0.1"))
true
cljs.user=> (boolean (re-matches re ".1"))
true
所以他们会被cljs.reader/read-string
.
读取字符串时"0.1"
,返回类型为 a js/Number
,但".1"
类型为cljs.core/Symbol
:
cljs.user=> (cljs.reader/read-string ".1")
.1
cljs.user=> (cljs.reader/read-string "0.1")
0.1
cljs.user=> (type (cljs.reader/read-string "0.1"))
#object[Number]
cljs.user=> (type (cljs.reader/read-string ".1"))
cljs.core/Symbol
因此,尽管看起来它正确地解析了 .1,但它实际上将它变成了一个符号。符号.1
不等于数字.1
。
请注意,在较新版本的 cuerdasparse-number
中不再可用,因为它“是一个字符串操作库而不是数字解析库”。
推荐阅读
- java - 将时间戳转换为字符串而不指定格式
- javascript - 如何以角度获取复选框值?
- linux - 从 1.5.8 升级到 1.6.7 后,未绑定速度降低 50%
- xml - XML 电话验证
- javascript - 检查值是否为时间戳的最佳方法是什么?
- javascript - 在元素中显示 HTML
- python - 调整excel单元格以适合图像
- flutter - Flutter 中的替代库,例如 iOS 中的可达性?
- python - ModuleNotFoundError:anaconda spyder 中没有名为“pyLDAvis”的模块
- haskell - 如何为 Mu 递归类型编写 Show 实例