【发布时间】:2012-07-09 04:27:19
【问题描述】:
在将一些 Fortran 翻译成 Scheme/Racket 时,我遇到了 功能:
; EPSILON(X) The least positive number that added
; to 1 returns a number that is greater than 1
如何在 Scheme 中找到号码?
【问题讨论】:
在将一些 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 中可能不是这种情况,我不知道),那么 machine epsilon 是众所周知的:对于双精度算术,它是 1.11e-16 .
对于其他平台或浮点实现,维基百科将计算公式显示为(在 Haskell 中):
main = print . last . map (subtract 1) . takeWhile (/= 1) . map (+ 1) . iterate (/2) $ 1
【讨论】:
这不是一个新的答案——只是让我感到困扰的是 Danny 的代码看起来很难做这种事情......它可以简化为
(let loop ([n 1.0])
(if (= 1 (+ 1 (/ n 2)))
n
(loop (/ n 2))))
【讨论】:
现有的答案是不必要的复杂,并可能导致不可移植的代码。
正确的答案是,如 Racket 的 math/flonum package 中所述,使用 epsilon.0 值,这对于当前机器是正确的,并且不需要您手动计算:
(require math/flonum)
epsilon.0
【讨论】: