Цель этого кода - , а не , чтобы найти наименьшее число с плавающей точкой, которое может поддерживать машина: это найти наименьшее число с плавающей точкой, epsilon
такое, что (= (+ 1.0 epsilon) 1.0)
является ложным. Это число полезно, потому что это верхняя граница ошибки, которую вы получаете при добавлении чисел. В частности, вы знаете, что, скажем, (+ x y)
находится в диапазоне [(x + y) * (1 - epsilon), (x + y) * (1 + epsilon)], где во втором выражении +
& c означают идеальные операции над числами.
В частности, (/ *machine-epsilon* 2)
является совершенно точным числом, как и (/ *machine-epsilon* 10000)
например, и (* (/ *machine-epsilon* x) x)
будет очень близко к *machine-epsilon*
для многих разумных значений x
. Это просто тот случай, когда (= (+ (/ *machine-epsilon* 2) 1.0) 1.0)
соответствует действительности.
Я недостаточно знаком со стандартами с плавающей точкой, но число, о котором вы, вероятно, думаете, это то, что Common Lisp называет least-positive-double-float
(или его варианты) , В Racket вы можете получить некоторое приближение к этому с помощью
(define *least-positive-mumble-float*
;; I don't know what float types Racket has if it even has more than one.
(let loop ([t 1.0])
(if (= (/ t 2) 0.0)
t
(loop (/ t 2)))))
Я не уверен, разрешено ли это вызывать исключение: на практике это не так, и он получает разумный ответ.