#:g1: (abs -0.0)の値

Posted 2021-08-25 01:30:35 GMT

Twitterで(abs -0.0)の値が話題になっていたので、Common Lispの処理系はどんな風になっているのか調べてみました。

-0.0 のサポート

まず、Common Lispでは-0.0をサポートしなくても良いようです。そもそもIEEE 754のサポートも必須ではなく、過去にはその辺りの選択は多分多様だったのでしょう。
IEEE 754をサポートしている場合には、*features*:ieee-floating-pointが入ることが推奨されています。

ちなみに実際に下記に出てくるVAX LISPなどはIEEE 754とは微妙に違う実装のようです。

VAX LISP[TM] V3.1
 Digital Equipment Corporation. 1989, 1990.
All Rights Reserved.

Lisp> *features* (EDITOR UIS COMPILER DEBUGGER :VMS VMS :DEC DEC :COMMON COMMON :VAX VAX :VAXLISP)

処理系が-0.0をサポートしているかどうかは、

(eql -0.0 0.0)
→ nil

かどうかで判定できると規格に書いてあります。

-0.0をサポートしていない処理系では、-0.0は、0.0として読み込まれるため、

(list -0.0L0 (abs -0.0L0))

の結果を確認すれば、(abs -0.0L0)の結果が正しいかを確認できそうです。

確認してみる

-0.0をサポートしている処理系

SBCL 1.4.8
(-0.0d0 0.0d0) → ok
CMUCL 21d
(-0.0d0 0.0d0) → ok
ABCL 1.7.0
(-0.0d0 0.0d0) → ok
ECL 21.2.1
(-0.0l0 0.0l0) → ok
MCL 3.0/5.2
(-0.0d0 0.0d0) → ok
LispWorks 7.1.3
(-0.0d0 -0.0d0) → ng
Lucid CL 4.1
(-0.0d0 -0.0d0) → ng

-0.0をサポートしていない処理系

Eclipse CL 1.1
(0.0d0 0.0d0)
CLISP 2.49.92
(0.0L0 0.0L0)
Allegro CL 10.1
(0.0d0 0.0d0)
Corman Lisp 3.1
(0.0d0 0.0d0)
AKCL 1.619
(0.0 0.0)
GCL 2.6.12
(0.0 0.0)
Xerox CL
(0.0 0.0)
VAX LISP
(0.0L0 0.0L0)

ということで、LispWorksとLucid CLだけ整合性がないという結果になりました。

まとめ

以上の結果が、Common Lispの規格として不整合なのかどうかはいまいち分からないのですが、LispWorksでも#C(-0.0 0)abs0.0だったりするようなので、float処理の場合だけ妙なことになっているのではないかと推察します。

(eql (abs #C(-0.0 0)) (abs #C(0.0 0)))
→ T

(eql (abs -0.0) (abs 0.0)) → nil

LispWorksにバグ報告してみたいような気もしますが、果してバグと言って良いのだろうか……。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus