3

これは、一般的な Lisp (clisp と sbcl) とスキーム (guile) の両方にあります。これらは真実ですが:

(= 1/2 0.5)
(= 1/4 0.25)

これは誤りであることが判明しました:

(= 1/5 0.2)

ハイパースペックを確認したところ、「=」は引数の型に関係なく数学的な同等性を確認する必要があると書かれています。一体何が起こっているのですか?

4

4 に答える 4

10

すべてのコンピュータ科学者が浮動小数点数について知っておくべきことをお読みください

于 2012-08-03T09:52:25.153 に答える
1

これは実際には、何が何に強制されるかによって異なります。考えてみれば、有理数の方が正確なので、float ではなく比較のために有理数に強制するのが理にかなっていますが、意識的に数値を float として比較したい場合は、以下のようにして強制することができます。

(declaim (inline float=))
(defun float= (a b)
  (= (coerce a 'float) (coerce b 'float)))
(float= 0.2 1/5) ; T

実際には...浮動小数点数は非数、正の無限大、負の無限大などを提供するため、それにはさらに多くのことがあります。たとえば、64 ビット浮動小数点数の場合、無限大は 10e200 iirc であるため、無限大よりも大きい (または負の無限大よりも小さい) 有理数を作成することを妨げるものは何もありません。それらのケースも考慮する必要があります。同様に、not-a-number との比較では、常に nil が返される必要があります...

于 2012-08-03T09:13:54.057 に答える
1

ただし、スキームでは正確な数値があるため、尋ねることができます ( #e プレフィックスに注意してください。これは、続く数値が正確に扱われることを意味します):

> (= 1/5 #e0.2)
#t
于 2012-08-03T12:11:55.617 に答える