Машина Эпсилон - найти Эпси


4.2 Машина Эпсилон

Найти числа с плавающей точкой epsi, который имеет на следующие свойства:

  1. 1.0+epsi-это больше, чем 1.0 и
  2. Пусть м б е любое число меньше Эпси. Затем 1.0+m равен 1.0.

Эпси называется Эпсилон. Это имеет большое значение в понимании чисел с плавающей точкой.

Я написал следующую программу, чтобы попробовать и найти мою машину значение Эпсилон на заданную глубину поиска (10). У вас есть какие-либо идеи, как я могу писать эту программу лучше?

(defpackage :find-epsi (:use cl))
(in-package :find-epsi)

(defun smaller-scale (&OPTIONAL (epsi 1.0)) (if (> (+ 1.0 epsi) 1.0) (smaller-scale (/ epsi 10)) epsi))
(defun bigger (epsi inc-unit) (if (< (+ 1.0 epsi) 1.0) (bigger (+ epsi inc-unit) inc-unit) epsi))
(defun smaller (epsi dec-unit) (if (> (+ 1.0 epsi) 1.0) (smaller (+ epsi dec-unit) dec-unit) epsi))

(defun find-epsi (&OPTIONAL (search-depth 10) (epsi (smaller-scale)) (incdec-unit epsi))
  (if (= search-depth 0) epsi (find-epsi (1- search-depth) (bigger (smaller epsi incdec-unit) incdec-unit) incdec-unit)))

(format t "epsi: ~a ~%" (find-epsi))

Кажется, что это должно быть намного проще, чтобы найти Эпсилон, чем я изначально думал. Что вы думаете о следующей программе?

(defpackage :find-epsi (:use cl))
(in-package :find-epsi)

(defun find-epsi (&OPTIONAL (epsi 1.0)) 
  (if (> (+ 1.0 epsi) 1.0)  ; if the variable epsi is still significant
    (find-epsi (/ epsi 2)) ; halve it and try again
    epsi)) ; otherwise, we have found epsilon

(format t "epsi: ~a ~%" (find-epsi))


340
2
задан 17 марта 2011 в 01:03 Источник Поделиться
Комментарии
1 ответ

Если мы предположим, что всплывают в памяти как (знак, мантисса, экспонента) кортеж, и предположить, основание 2, то мы можем найти именно ту машину Эпсилон. То есть, если мы можем предположить, что машина плавает магазинах, используя базовый-2 представлений мантиссы и экспоненты, то мы знаем, что:


  • Машина будет храниться значение 1 в плавающей точке ровно - это будет храниться как 1 для мантиссы и 0 для показателя степени, т. е. 1 * 2^0.
  • Машина будет хранить все полномочия, которые он может представлять, используя один бит в мантиссе, и различной степени. Е. Г. 1/4 может быть представлена как 1 * (2 ^ -2). Любое представимое мощность двух будет храниться без потери информации.
  • 1 + Эпси будет наименьшим значением больше 1, который может храниться в мантиссе числа с плавающей запятой.

Редактировать

Вторая версия выглядит намного лучше, чем первый, но я верю, что есть офф-по одной ошибке в сколько раз вам повторить В найти-Эпси. Я предлагаю вам создать функцию тест, чтобы увидеть, если ваш результат-машина Эпсилон:

(defun epsi-sig-p (epsi)
(> (+ 1.0 epsi) 1.0))

Вы, вероятно, обнаружите, что (это-сиг (найти-Эпси)) это ... это также предполагает, что вы можете выполнить рефакторинг (под сухой принцип) найти-Эпси использования этой функции В найти-Эпси:

(defun find-epsi (&OPTIONAL (epsi 1.0))
(if (epsi-sig-p epsi)
(find-epsi (/ epsi 2))
epsi))

но мы не изменить поведение, чтобы исправить расчет, пока. Для этого я предлагаю еще одну процедуру, чтобы проверить, действительно ли мы должны попробовать следующий возможный Эпси:

(defun next-epsi (epsi) (/ epsi 2))
(defun is-epsi-p (epsi)
(and (epsi-sig-p epsi) (not (epsi-sig-p (next-epsi epsi)))))
(defun find-epsi (&OPTIONAL (epsi 1.0))
(if (is-epsi-p epsi)
epsi
(find-epsi (next-epsi epsi))))

это-Эпси-п должны вернуть , теперь.

3
ответ дан 17 марта 2011 в 10:03 Источник Поделиться