逆引きxyzzy lisp(数値) - circleratio/xyzzy GitHub Wiki

目次

数の表現

2進数・8進数・16進数で数値を扱うには

それぞれ以下のように記述する.

#b0111
=> 7

#o010
=> 8

#xffff
=> 65535

数値を2進数・8進数・10進数・16進数表現の文字列に変換するには

それぞれ以下のように記述する.

(format t "binary ~B" 32)
=> binary 100000
   nil

(format t "octal ~O" 8)
=> octal 10
   nil

(format t "decimal ~D" #xff)
=> decimal 255
   nil

(format t "hex ~X" 255)
=> hex ff
   nil

浮動小数点数値の精度を指定する

xyzzy では float, double それぞれに相当する区別がある. double を指定する方法は次の通り.

0.1234d0
=> 0.1234d0

複素数

実数部と虚数部を指定して複素数を表現。

(setq a (complex 0 1))
=> #C(0 1)

(setq b (complex 0 1))
=> #C(0 1)

(* a b)
=> -1

(+ a b)
=> #C(0 2)

conjugate は共役複素数を求める。

(conjugate a)
=> #C(0 -1)

実数部、虚数部、偏角は realpart, imagpart, phase で取り出せる。

(realpart a)
=> 0

(imagpart a)
=> 1

(phase a)
=> 1.570796

ビット演算

and, or, not, xor, シフト演算

logand, logior, lognot, logxor がそれぞれ AND, OR, NOT, XOR となる.

シフト演算は ash で行う. 引数の符号でシフト方向を指示する.

(ash #b0010 1)
=> 4

(ash #b0010 -1)
=> 1

emacs lisp には lsh があるが,xyzzy lisp にはない.

任意のビット位置の値を参照する

(logbitp 0 #b0001)
=> t

(logbitp 1 #b0001)
=> nil

1または0のビット個数を数える

引数に正の値を指定すると 1 の個数を返し,負の値を指定すると 0 の個数を返す.

(logcount #b00111)
=> 3

(logcount #b-00111)
=> 2

算術演算

除算の商と余りを求める

商だけを求めるなら次のようにする.

(truncate 7 3)
=> 2
   1

剰余だけなら次.

(mod 10 3)
=> 1

(rem 10 3)
=> 1

商と余りを同時に求めるなら,multiple-value-list を使う.

(multiple-value-list (truncate 10 3))
=> (3 1)

絶対値を求める

(abs -1)
=> 1

三角関数を計算する

(sin (/ pi 2.0))
=> 1.0d0

(cos pi)
=> -1.0d0

(tan (/ pi 4.0))
=> 0.9999999999999999d0

対数を計算する

(log 100 10)
=> 2.0

引数がひとつの場合は自然対数.

(log 10)
=> 2.302585

べき乗を計算する

(expt 2 10)
=> 1024

平方根を求める

(sqrt 100)
=> 10.0

変換

切り上げ

プラス方向の整数に丸める.

(ceiling 1.5)
2

(ceiling -1.5)
-1

切り捨て

小数点以下を切り捨てるなら truncate, マイナス方向の整数に丸めるなら floor. 両者は負の値の場合の結果が異なる.

(floor 1.5)
1

(floor -1.5)
-2

(truncate 1.5)
1

(truncate -1.5)
-1

四捨五入

近いほうの整数に丸める. 0.5の場合は偶数方向にまとめる.

(round 1.5)
2

(round 1.4)
1

(round -1.5)
-2

(round -1.4)
-1

分数を小数にする

(/ 3 2)
=> 3/2

(float (/ 3 2))
=> 1.5

小数を分数にする

(rationalize 1.5)
=> 3/2

実数を有理数に変換する

(rational 0.33)
=> 11072963/33554432

乱数を生成する

(random 100)
=> 42

数を調べる

ある値(or リスト)が min...max の範囲に入っているかどうかを調べる

(defun range-check (min max val)
  (let ((cmp (lambda (v)
	       (and (>= v min) (>= max v)))))
    (if (listp val)
	(every #'identity (mapcar cmp val))
      (funcall cmp val))))

数値の符号を調べる

(signum 10)
=> 1

(signum 0.0)
=> 0.0

(signum -5)
=> -1

算法

最小公倍数、最大公約数を求める

(lcm 2 4 6)
=> 12

(gcd 2 4 6)
=> 2

素因数分解をする

(defun prime-factor (n d)
  (let ((max (truncate (sqrt n))))
    (cond ((= (mod n d) 0) (cons d (prime-factor (/ n d) d)))
	  ((= d max) n)
	  ((= n 1) nil)
	  (t (prime-factor n (1+ d))))))

(prime-factor 21 2)
=> (3 7)

(prime-factor 65535 2)
=> (3 5 17 257)
⚠️ **GitHub.com Fallback** ⚠️