Parsing 在ClojureScript程序中使用Cuerdas解析十进制数
我正在使用一个 ClojureScript程序解析浮点数。有时,来自 用户缺少完整的部分,如Parsing 在ClojureScript程序中使用Cuerdas解析十进制数,parsing,floating-point,numbers,decimal,clojurescript,Parsing,Floating Point,Numbers,Decimal,Clojurescript,我正在使用一个 ClojureScript程序解析浮点数。有时,来自 用户缺少完整的部分,如0.1的.1。我需要处理这件事。 但我在比较解析的数字时遇到了奇怪的结果: (= 0.1 (parse-number "0.1")) ;; => true (= .1 (parse-number "0.1")) ;; => true (= 0.1 (parse-number ".1")) ;; => false (= .1
0.1
的.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
上面最后两个结果令我惊讶。当比较字面值I时
获得预期结果:
(= 0 .0)
;; => true
当我只解析没有整数的十进制数时,这种奇怪的行为也是可见的
第二部分,如下所示:
(parse-number ".1")
;; => .1
.1
;; => 0.1
我发现我可以使用js/parseFloat
得到我想要的东西,但我很好奇
使用Cuerdas时出现这种行为的原因是什么?这个.1
值是什么
它与0.1
有何不同?源代码如下:
(defn解析号
“用于解析数字的通用函数,如
字符串到数字。它同时适用于两个整数
和浮动。”
[s]
(如无)
#(:cljs js/NaN:clj Double/NaN)
(如果(数字?s)
(edn/读取字符串s)
#(:cljs js/NaN:clj Double/NaN)))
“.1”
和“0.1”
都被认为是(通过正则表达式检查在cuerdas中实现):
cljs.user=>(定义为“^[+-]?([0-9]*\.?[0-9]+[0-9]+\.?[0-9]+\)([eE][+-]?[0-9]+)?$”)
#'cljs.user/re
user=>(布尔值(重新匹配“0.1”))
真的
cljs.user=>(布尔值(重匹配重“.1”))
真的
因此,他们将被阅读
读取字符串“0.1”
时,返回类型为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=>(类型(cljs.reader/read-string“0.1”))
#对象[编号]
cljs.user=>(类型(cljs.reader/read-string“.1”))
cljs.core/Symbol
因此,尽管它看起来正确地解析了.1,但实际上它将其转换为一个符号。符号.1
不等于数字.1
请注意,parse number
属于cuerdas,因为它“是一个字符串操作库,而不是一个数字解析库”。我有一些适用于CLJ和CLJS的库。从单元测试中,我们得到了
标题:
(ns tst.tupelo.parse
;---------------------------------------------------------------------------------------------------
; https://code.thheller.com/blog/shadow-cljs/2019/10/12/clojurescript-macros.html
; http://blog.fikesfarm.com/posts/2015-12-18-clojurescript-macro-tower-and-loop.html
#?(:cljs (:require-macros
[tupelo.misc]
[tupelo.testy]))
(:require
[clojure.test] ; sometimes this is required - not sure why
[tupelo.parse :as tpar]
[tupelo.misc :as misc]
[tupelo.core :as t :refer [spy spyx spyxx spyx-pretty]]
[tupelo.testy :refer [deftest testing is dotest isnt is= isnt= is-set= is-nonblank=
throws? throws-not? define-fixture]])
#?(:clj (:import [java.lang Math]))
)
解析整数:
#?(:cljs
(do
(dotest
(is= 0 (tpar/parse-int "0"))
(is= 15 (tpar/parse-int "15"))
(is= -5 (tpar/parse-int "-5"))
(is= 99999 (tpar/parse-int "99999"))
(throws? (tpar/parse-int ""))
(throws? (tpar/parse-int "05"))
(throws? (tpar/parse-int "123xxx"))
(throws? (tpar/parse-int "12x3"))
(throws? (tpar/parse-int "12.3"))
(throws? (tpar/parse-int "xxx123")))
分析浮动
(dotest
(is= 0 (tpar/parse-float "0"))
(is= 0 (tpar/parse-float "0.0"))
(is= 12.345 (tpar/parse-float "12.345"))
(is= -5.1 (tpar/parse-float "-5.1"))
(is= 42 (tpar/parse-float "42.0"))
(is= 42 (tpar/parse-float "42"))
(is= 123.45 (tpar/parse-float "1.2345e2"))
(throws? (tpar/parse-float ""))
(throws? (tpar/parse-float "xxx1.23"))
(throws? (tpar/parse-float "1.23xxx"))
(throws? (tpar/parse-float "1.2xx34")))
))
谢谢,我会试试的。