浮動小数点数は、整数ではない数値を表現するのに有用です。浮動小数点数の範囲は、使用しているマシンにおけるC言語のデータ型 double の範囲と同じです。Emacsがサポートするほぼすべてのコンピュータでは、これは IEEE binary64 浮動小数点形式であり、IEEE Std
754-2019 で標準化されています。詳細については、David Goldberg氏の論文 “What
Every Computer Scientist Should Know About Floating-Point
Arithmetic”
で解説されています。現代のプラットフォームでは、浮動小数点演算はIEEE-754規格に密接に準拠していますが、一部のシステム(特に32ビットx86)では、結果が正しく丸められないことがあります。
一部の旧式コンピュータシステムでは、EmacsがIEEE浮動小数点形式を使用しない場合があります。Emacsが正常に動作するものの、IEEE-754に準拠していないシステムが1つ知られています。それはGCC 10.4.0を用いてNetBSDが動作しているVAXで、代わりにVAXの「D_Floating」形式が使用されています。IBM System/370系メインフレームとそのXL/Cコンパイラも16進浮動小数点形式を利用できますが、そのような構成でEmacsがビルドされたことはまだありません。
浮動小数点数の読み取り構文では、小数点、指数、またはその両方が必要です。省略可能な符号(‘+’ または ‘-’)は、数値とその指数の前に記述します。例えば、‘1500.0’、‘+15e2’、‘15.0e+2’、‘+1500000e-3’、および ‘.15e4’ は、値が 1500 となる浮動小数点数の 5 通りの書き方です。これらはすべて等価です。Common Lisp と同様に、Emacs Lisp では、指数を持たない浮動小数点数において、小数点の後に少なくとも 1 桁の数字が必要です。‘1500.’ は整数であり、浮動小数点数ではありません。
Emacs Lispでは、-0.0を=のような数値比較において、通常のゼロと数値的に等しいものとして扱います。これはIEEE浮動小数点規格に準拠したもので、同規格では、他の演算では区別できる場合であっても、-0.0と0.0は数値的に等しいとされています。
IEEE浮動小数点規格では、正の無限大と負の無限大を浮動小数点値としてサポートしています。また、NaN(「not
a number」)と呼ばれる値のクラスも規定されており、数値関数は正しい答えが得られない場合にこのような値を返します。例えば、(/ 0.0
0.0)はNaNを返します。NaNは、自分自身を含め、いかなる値とも数値的に等しくなることはありません。NaNは符号と仮数を持ち、非数値関数は、符号と仮数が一致する場合に2つのNaNを等しいものとして扱います。NaNの仮数および文字列表現における各桁は、マシン依存となります。
NaNや符号付きゼロが関わる場合、eql、equal、sxhash-eql、sxhash-equal、gethashといった非数値関数は、値が数値的に等しいかどうかではなく、区別不能であるかどうかを判定します。例えば、xとyが同一のNaNである場合、(equal x y)はtを返しますが、(= x y)は数値比較を行いnilを返します。逆に、(equal 0.0
-0.0)はnilを返しますが、(= 0.0
-0.0)はtを返します。
これらの特殊な浮動小数点値の読み取り構文は以下の通りです。
‘1.0e+INF’と‘-1.0e+INF’
‘0.0e+NaN’と‘-0.0e+NaN’
IEEE浮動小数点演算機能を備えていないレガシーシステムでは、無限大やNaNは利用できません。例えば、1980年頃のVAXでは、Lispは‘1.0e+INF’を大きな有限の浮動小数点数として、‘0.0e+NaN’を数値として使用するとエラーを発生させる別の非数値的なLispオブジェクトとして読み取っていました。
以下の関数は、浮動小数点数の処理に特化しています。
この述語は、浮動小数点引数がNaNの場合はtを、それ以外の場合はnilを返します。
この関数はコンスセル (s . e) を返します。ここで s と e は、それぞれ浮動小数点数 x の仮数部と指数部です。
x が有限数の場合、s は 0.5(含む)から 1.0(含まない)までの浮動小数点数、e は整数、x = s * 2**e となります。x が 0 または無限大の場合、s は x と同じ値になります。x が NaN の場合、s も NaN となります。x が 0 の場合、e は 0 となります。
数値の仮数部 s と整数の指数部 e が与えられたとき、この関数は浮動小数点数 s * 2**e を返します。
この関数は、x2の符号をx1の値にコピーし、その結果を返します。x1およびx2は浮動小数点数である必要があります。
この関数は x の2進指数を返します。より正確には、x が有限かつ非ゼロの場合、値は |x| の2を底とする対数を整数に切り下げたものです。x がゼロまたは無限大の場合、値は無限大となり、x が NaN の場合、値は NaN となります。
(logb 10)
⇒ 3
(logb 10.0e20)
⇒ 69
(logb 0)
⇒ -1.0e+INF