Небольшое отклонение в точности с плавающей точкой (im), часть 1 - PullRequest
20 голосов
/ 04 августа 2008

Большинство математиков согласны с тем, что:

e πi + 1 = 0

Однако большинство реализаций с плавающей запятой не согласны. Насколько хорошо мы можем уладить этот спор?

Мне очень хотелось бы услышать о разных языках и реализациях, а также о различных методах, позволяющих сделать результат максимально близким к нулю. Будьте креативны!

Ответы [ 10 ]

17 голосов
/ 26 декабря 2008

Дело не в том, что большинство реализаций с плавающей точкой не согласны, просто они не могут получить точность, необходимую для получения 100% ответа. И правильный ответ: они не могут.

PI - это бесконечный ряд цифр, который никто не смог обозначить ничем, кроме символического представления, и e ^ X - это то же самое, и, таким образом, единственный способ достичь 100% точности - это перейти на символ.

10 голосов
/ 04 августа 2008

Вот краткий список реализаций и языков, которые я пробовал. Отсортировано по близости к нулю:

  • Схема: (+ 1 (make-polar 1 (atan 0 -1)))
    • 0.0+1.2246063538223773e-16i (схема Chez, схема MIT)
    • 0.0+1.22460635382238e-16i (Guile)
    • 0.0+1.22464679914735e-16i (Курица с numbers яйцом)
    • 0.0+1.2246467991473532e-16i (MzScheme, SISC, Gauche, Gambit)
    • 0.0+1.2246467991473533e-16i (SCM)
  • Обычный Лисп: (1+ (exp (complex 0 pi)))
    • #C(0.0L0 -5.0165576136843360246L-20) (CLISP)
    • #C(0.0d0 1.2246063538223773d-16) (CMUCL)
    • #C(0.0d0 1.2246467991473532d-16) (SBCL)
  • Perl: use Math::Complex; Math::Complex->emake(1, pi) + 1
    • 1.22464679914735e-16i
  • Python: from cmath import exp, pi; exp(complex(0, pi)) + 1
    • 1.2246467991473532e-16j (CPython)
  • Рубин: require 'complex'; Complex::polar(1, Math::PI) + 1
    • Complex(0.0, 1.22464679914735e-16) (МРТ)
    • Complex(0.0, 1.2246467991473532e-16) (JRuby)
  • R: complex(argument = pi) + 1
    • 0+1.224606353822377e-16i
7 голосов
/ 04 августа 2008

Можно ли уладить этот спор?

Моя первая мысль - взглянуть на символический язык, например Maple . Я не думаю, что это считается плавающей точкой.

На самом деле, как можно представить i (или j для инженеров) на обычном языке программирования?

Возможно, лучшим примером является грех (π) = 0? (Или я снова упустил суть?)

5 голосов
/ 25 августа 2008

Ваш вопрос кажется мне немного странным, так как вы, кажется, предполагаете, что математика с плавающей точкой реализована языком. Как правило, это не так, поскольку математика FP выполняется с использованием аппаратного процессора с плавающей запятой. Но программная или аппаратная, с плавающей точкой всегда будет неточной. Вот как работают поплавки.

Если вам нужна лучшая точность, вам нужно использовать другое представление чисел. Также как если вы делаете целочисленную математику для чисел, которые не вписываются в int или long. Некоторые языки имеют встроенные библиотеки (я знаю, что в java есть BigInteger и BigDecimal), но вам придется явно использовать эти библиотеки вместо нативных типов, и производительность будет (иногда значительно) хуже, чем если бы вы использовали float. 1003 *

5 голосов
/ 25 августа 2008

Я согласен с Райаном, вам нужно перейти к другой системе представления чисел. Решение находится за пределами математики с плавающей запятой, потому что вам нужно, чтобы число pi представлялось в виде бесконечно длинного десятичного числа, поэтому любая схема с ограниченной точностью просто не будет работать (по крайней мере, без использования какого-либо фадж-фактора, чтобы составить потерянный точность).

4 голосов
/ 06 мая 2017

У меня были очень приятные кофейные чаты, и мой лучший друг говорил о иррациональных числах и разнице между другими числами. Что ж, мы оба согласны с этой другой точкой зрения:

Иррациональные числа - это отношения, как функции, каким-то образом? Хорошо, подумайте: «Если вы хотите идеальный круг, дайте мне идеальный пи», но круги отличаются от других фигур (4 стороны, 5, 6 ... 100, 200), но ... Сколько еще сторон делают у вас, больше похоже на круг это выглядит. Если вы до сих пор следовали за мной, то соедините все эти идеи с помощью формулы Пи: enter image description here

Итак, пи - это функция, но она никогда не заканчивается! из-за параметра ∞, но мне нравится думать, что у вас может быть «экземпляр» числа pi, если вы измените параметр ∞ для очень большого значения Int, у вас будет очень большой экземпляр числа pi.

То же самое с е, дай мне огромный параметр, я дам тебе огромный е.

Собираем все идеи вместе:

Поскольку у нас есть ограничения памяти, язык и библиотеки предоставляют нам огромное количество иррациональных чисел, в этом случае, пи и е, в качестве конечного результата, у вас будет долгий подход к получению 0, как в примерах @Chris. Jester-Young

4 голосов
/ 25 августа 2008

@ Райан Фокс

На самом деле, как представить меня (или j для инженеров) на обычном языке программирования?

Собственные сложные типы данных далеко не известны. У Фортрана это было к середине шестидесятых, и ОП демонстрирует множество других языков, которые поддерживают их в истории.

И комплексные числа могут быть добавлены к другим языкам в виде библиотек (при перегрузке операторов они даже выглядят как нативные типы в коде).

Но если вы не предоставите особый случай для этой проблемы, «несогласие» является просто выражением неточной машинной арифметики, не так ли? Это все равно что жаловаться, что

float r = 2/3;
float s = 3*r;
float t = s - 2;

заканчивается на (t! = 0) (по крайней мере, если вы используете достаточно тупой компилятор) ...

3 голосов
/ 20 ноября 2009

Это ограничение нашей текущей вычислительной архитектуры с плавающей запятой. Арифметика с плавающей запятой - это только приближение числовых полюсов, таких как e или pi (или что-то сверх точности, которую позволяют ваши биты) Мне действительно нравятся эти числа, потому что они не поддаются классификации и имеют большую энтропию (?), Чем даже простые числа, которые являются каноническими рядами. Числовое представление не поддается соотношению, иногда простые вещи могут взорвать человеческий разум (мне это нравится).

К счастью, целые языки и библиотеки могут быть выделены для прецизионных тригонометрических функций с использованием нотационных понятий (аналогичных тем, которые описаны Lasse V. Karlsen ).

Рассмотрим библиотеку / язык, который описывает такие понятия, как e и pi, в форме, понятной машине. Есть ли у машины представление о том, что такое идеальный круг? Возможно, нет, но мы можем создать объект - круг, который удовлетворяет всем известным признакам, которые мы ему приписываем (постоянный радиус, отношение радиуса к окружности равно 2 * pi * r = C). Объект, подобный пи, описывается только вышеупомянутым отношением. R & C могут быть числовыми объектами, описанными с любой точностью, которую вы хотите им дать. e можно определить как «e - это уникальное действительное число, такое, что значение производной (наклон касательной линии) функции f (x) = ex в точке x = 0 равно 1» из википедия .

Забавный вопрос.

3 голосов
/ 27 декабря 2008

Численный анализ учит нас, что вы не можете полагаться на точное значение небольших различий между большими числами.

Это не только влияет на рассматриваемое здесь уравнение, но может привести к нестабильности во всем: от решения почти сингулярной системы одновременных уравнений, нахождения нулей полиномов, до вычисления log (~ 1) или exp (~ 0) (я даже видел специальные функции для оценки log (x + 1) и (exp (x) -1), чтобы обойти это).

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

Извините, прошло 43 года с тех пор, как я вбил в меня это в универе, и даже если бы я мог вспомнить ссылки, я уверен, что сейчас есть вещи получше. Я предлагаю это в качестве отправной точки.


Если это звучит немного покровительственно, я прошу прощения. Мой «Числовой анализ 101» был частью моего курса химии, так как в те дни не было много CS. У меня нет особого представления о том, какое место / значение имеет численный анализ в современном курсе CS.

3 голосов
/ 25 августа 2008

На самом деле, как представить меня (или j для инженеров) на обычном языке программирования?

На языке, который не имеет нативного представления, он обычно добавляется с использованием ООП для создания Complex класса, представляющего i и j, с перегрузкой оператора для правильной обработки операций, связанных с другими * 1008. * числа и / или другие числовые примитивы, родные для языка.

Например: Complex.java , C ++

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...