在将一些 Fortran 翻译成 Scheme/Racket 时,我遇到了这个函数:
; EPSILON(X) The least positive number that added
; to 1 returns a number that is greater than 1
如何在 Scheme 中找到号码?
#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 中可能不是这种情况,我不知道),那么机器 epsilon是众所周知的:对于双精度算术,它是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))))
现有的答案是不必要的复杂,并可能导致不可移植的代码。
正确的答案是,如 Racket 的math/flonum 包中所述,使用 epsilon.0 值,这对于当前机器是正确的,并且不需要您手动计算:
(require math/flonum)
epsilon.0