一部の Fortran を Scheme/Racket に変換しているときに、次の関数に出くわしました。
; EPSILON(X) The least positive number that added
; to 1 returns a number that is greater than 1
スキームで番号を見つけるにはどうすればよいですか?
#lang racket/base
;; http://en.wikipedia.org/wiki/Machine_epsilon
;; approximates the machine epsilon
(require racket/flonum)
(define (compute-machine-epsilon)
(let loop ([n 1.0])
(define next-n (fl/ n 2.0))
(if (fl= 1.0 (fl+ 1.0 next-n))
n
(loop next-n))))
IEEE-754 浮動小数点を使用していると仮定すると (Scheme ではそうではないかもしれませんが、私にはわかりません)、マシンのイプシロンはよく知られています。倍精度演算の場合、それは1.11e-16
.
他のプラットフォームまたは浮動小数点実装の場合、ウィキペディアはそれを計算する式を (Haskell で) 示しています。
main = print . last . map (subtract 1) . takeWhile (/= 1) . map (+ 1) . iterate (/2) $ 1
これは新しい答えではありません-ダニーのコードがこの種のことを行うのが難しいように見えるのは私を悩ませているだけです...
(let loop ([n 1.0])
(if (= 1 (+ 1 (/ n 2)))
n
(loop (/ n 2))))