Overview

Clojureにおける数値及び演算についてまとめる.

ClojureはJavaのラッパーのため, バックグラウンドとして📝Java Numberの知識がほしい.

java.lang.Math Interop

基本戦略としてJava.lang.Mathに定義されている関数が役に立ち, これらの直呼びは悪くない. 結局ClojureもJavaの関数を呼び出しているに過ぎない.

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Math.html

Clojureはclojure.math namespaceにjava8のMath関連のwrapperがあるが, これは全て網羅されているのかな?

https://clojure.github.io/clojure/clojure.math-api.html

Clojureではdefaultでjava.lang配下はincludeされているため, Mathを呼び出すには Math/xxx でいける.

数値型Basics

primitive な数値のデータ型3種類ある.

  • integer
  • floating point
  • ratio

整数(integer)

整数は固定精度64ビット整数として, その範囲にない場合には任意精度整数として読み取られる.

末尾に N を付けることで強制的に任意精度にすることができる.

浮動小数点数(floating point)

Clojureで扱える型はJavaのDouble型とBigDecimal型.

基本的にはDouble型をつかうことになり, 精度が求められる場合のみBigDecimalをつかう.

数値の末尾に M がつくとBigDecimal型. として扱われる. そうでなければDouble型.

doubleとfloatの違いは?

Clojureにはdoubleの代わりにfloatもある.

  • double: java.lang.Double, 64bit, 有効桁数7, 末尾にM.
  • float: java.lang.Float, 32bit, 有効桁数15

通常はdouble, メモリを節約したいときはfloat.


おそらくだが, Clojureとしてはdoubleとbigdecimalで事足りと考えていてfloatはJavaとの互換性.

分数(ratio)

割り算 / はratioという特殊なデータ型に保存されて即時に計算されないことがClojureの独自であり特徴.

計算Basics

基礎的な計算まとめ.

高度な話題は📝Clojure Data Scienceへ.

商とRatio

Clojureにおいて / をつかって計算しても評価をされない. Ratioというデータ型に格納されて評価を待っているだけ. 評価を強制するには小数点をつける.

(/ 22 7.0)

quot をつかうと商のみをとりだすことができる.

余り(rem/mod)

余りの関数にはrem/modの2種類があり, 負の数を扱う時rem.

ref. Clojureの剰余を求める関数、remとmodの違い - Qiita

対数

Math/log, Math/log10をつかう.

指数

Math/expをつかう.

べき乗

Math/powをつかう.

(def e10 (Math/pow 10 -10))

Cookbook

整数に丸める

javaのMath/round, Math/ceil, Math/floorが簡単.

roundはint型, ceil/floorはdouble型になることに注意.

Math/floorとintをつかう方法.

(defn round [x] (int (Math/floor x)))

小数点以下を文字列変換で切り捨てる(floor)

ref. clojure-cookbook/1-16_rounding.asciidoc at master · clojure-cookbook/clojure-cookbook · GitHub

単にログ出力のためならば clojure.core/formatをつかうのがいい.

(format "%.2f" x)

さらにそれをparseDoubleでDoubleに変換.

(Double/parseDouble (format "%.2f" 0.009) )

小数点以下を文字列変換で四捨五入(round)

Math/round をつかう方法とBigDecimalをつかう方法の2つ.

(/ (Math/round (* (/ 1.0 3) 1e3)) 1e3)
 
(with-precision 3 (/ (bigdec 1) 3))

Clojureで数値に3桁ごとにカンマを入れる方法

(format "%,d" 33333)
;; => "33,333"

正数を負数にする

- はclojure.core/-という単数なので, 関数を呼び出すようにして正負を反転させる.

(def a 1)
(- a) ;= -1

Libraries