iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
1
Software Development

擁抱 Clojure系列 第 4

[第 04 天] 擁抱 Clojure:資料結構與型態(一)

資料結構與型態(一)

本篇文章將介紹 Clojure 內建的的資料結構與型態,會先從簡單的資料型態如數字及字串開始,再介紹複雜的資料結構如群集 (Collection) 與序列 (Sequence)。

數字 (Number)

整數

在 Clojure 中,整數的表示法與主流程式語言無異,如果沒有特別聲明,預設爲十進位表示法。大小爲 64 位元有號整數,內部使用的型態爲 Java 中的 long:

(class 42)
;; => java.lang.Long
42
;; => 42
-42
;; => -42

除了十進位表示法之外,也提供了八進位、十六進位的表示法:

0x2a
;; => 42
052
;; => 42

在數字前面加上 0 被視爲八進位表示法、前面加上 0x 則是十六進位表示法。也可以自行決定數字的基底,只要在數字前面加上想要使用的基底 (範圍從 2 到 36),再加上 r 即可:

2r101010
;; => 42
16r2A
;; => 42

浮點數

Clojure 的浮點數表示法也與主流程式語言無異,採用的是 IEEE 754 雙精度標準,大小爲 64 位元,內部使用的型態爲 Java 中的 double:

(class 3.14)
;; => java.lang.Double
3.14
;; => 3.14
1.618
;; => 1.618

以指數的方式表現:

3.14e-2
;; => 0.0314
+1.618e-1
;; => 0.1618

有理數

Clojure 爲了支持高精度的計算,提供了有理數型態。舉例來說,在其他主流程式語言裡,1/3 的結果爲 0.3333…,或是將浮點數相加起來,原有的精確度反而在計算中喪失了:

>>> 1.0 / 3.0
0.3333333333333333
>>> 0.1 + 0.1 + 0.1
0.30000000000000004

使用有理數型態作運算,不會經過不必要的轉換而喪失準確度,只有在需要的時候,由使用者決定是否該轉換型態。內部使用的型態爲 clojure.lang.Ratio。

(class (/ 1 3))
;; => clojure.lang.Ratio
(/ 1 3)
;; => 1/3
(+ 1/10 1/10 1/10)
;; => 3/10

你可以將有理數轉型成浮點數:

(double 1/3)
;; => 0.3333333333333333

也可以將浮點數轉型成有理數:

(rationalize 0.3)
;; => 3/10

大數

一般來說,預設提供的 64 位元整數與浮點數已經綽綽有餘,但是如果需要處理超過 64 位元範圍的數值,就需要使用到 Clojure 提供的兩個大數型態:大整數 (BigInt)、大浮點數 (BigDecimal)。內部使用的型態分別爲 clojure.lang.BigInt 以及 java.math.BigDecimal。

(class 1N)
;; => clojure.lang.BigInt
(class 2M)
;; => java.math.BigDecimal

大整數的表示法爲在數字後加上大寫的 N;大浮點數則是在數字後加上大寫的 M。內建的 +-*/incdec 等運算元,作用在整數時如果超出 64 位元範圍 (overflow),會出現錯誤而拋出例外。如果想避免錯誤,讓 Clojure 把結果套用到大數上,則必須使用大數版的運算元,即在運算元後加上單引號 (‘):

(+ 9141592653589793238 9141592653589793238)
;; => ArithmeticException integer overflow
(+' 9141592653589793238 9141592653589793238)
;; => 18283185307179586476N

運算

基本的四則運算與其他主流程式語言一樣,需要注意的是 Clojure 採用前置表示法:運算元擺在小括號的第一個位置:

(+ 1 2)
;; => 3
(- 1 3)
;; => -2
(* 2 4)
;; => 8
(/ 6 3)
;; => 2

如果想要獲得整數除法運算的商,可以使用 quot 函式:

(quot 47 7)
;; => 6

取得除法運算的餘,則使用 rem 函式:

(rem 47 7)
;; => 5

(未完待續)


上一篇
[第 03 天] 擁抱 Clojure:基本組成(二)
下一篇
[第 05 天] 擁抱 Clojure:資料結構與型態(二)
系列文
擁抱 Clojure30

尚未有邦友留言

立即登入留言