Арифметика действительных чисел в языке общего назначения? - PullRequest
3 голосов
/ 17 сентября 2010

Как (надеюсь) большинство из вас знает, арифметика с плавающей запятой отличается от арифметики действительных чисел.Это для начала неточно.Многие числа, особенно десятичные (0,1, 0,3), не могут быть представлены, что приводит к таким проблемам, как this .Более подробный список можно найти здесь .

Существуют ли какие-либо языки общего назначения , которые имеют встроенную поддержку чего-то более близкого к арифметике действительных чисел?Если нет, то какие хорошие библиотеки поддерживают это?

РЕДАКТИРОВАТЬ: Произвольная точность decimal типы данных не , что я ищу.Я хочу иметь возможность представлять числа типа 1/3, sqrt(3) или 1 + 2i.

Ответы [ 12 ]

2 голосов
/ 17 сентября 2010

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

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

2 голосов
/ 17 сентября 2010

Хотя я ненавижу это говорить, Фортран.Он имеет обширную поддержку арифметики произвольной точности и тонны поддержки для вычислений большого числа.Он древний и грубый, но он выполняет свою работу.

1 голос
/ 17 сентября 2010

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

> (+ 1/2 1/3)
5/6
> (* 3 1+1/2i)
3+3/2i
> (+ 1/2 .5)
1.0

Если вы хотите выйти за пределы рациональных чисел или комплексных чисел с рациональными коэффициентами, до алгебраических чисел, таких как sqrt(2), или чисел в замкнутой форме, таких как e , вы, вероятно, будете иметь выходить за рамки языков программирования общего назначения и использовать математический язык специального назначения, такой как Mathematica или Maxima.

1 голос
/ 17 сентября 2010

Этот вопрос интересен, но поднимает некоторые вопросы.Во-первых, вы никогда не сможете представить все действительные числа с помощью (даже теоретически бесконечного) компьютера по причинам кардинальности.

То, что вы ищете, - это тип данных "символические числа",Вы можете представить себе своего рода дерево выражений с предопределенными константами, арифметическими операциями и, возможно, алгебраическими (корни многочленов) и трансцендентными (exp, sin, cos, log и т. Д.) Функциями.

Теперь забавная частьистория: вы не можете найти алгоритм, который сообщает, представляют ли два таких дерева одно и то же число (или, что эквивалентно, проверяет, является ли такое дерево нулевым).Я не буду утверждать ничего точного, но в качестве подсказки это похоже на проблему Остановки (для компьютерных ученых) или теорему Гёделя о неполноте (для математиков).

Это делает такой класс довольно бесполезным.

Для некоторых подполей вещественных чисел у вас есть канонические формы , такие как a / b для рациональных чисел или конечные алгебраические расширения рациональных чисел (a / b + ic / d для комплексных рациональных чисел,a / b + sqrt (2) * a / b для Q [sqrt (2)] и т. д.).Они могут использоваться для представления некоторых конкретных наборов алгебраических чисел.

На практике это самая сложная вещь, которая вам понадобится.Если у вас есть особая необходимость, например диапазоны чисел с плавающей запятой (до доказать , то какой-то результат за указанный интервал, это, вероятно, самое близкое значение, которое вы можете получить к действительным числам) или числа произвольной точности , у вас есть свободно доступные классы везде.Google boost::range для первого и gmp для второго.

1 голос
/ 17 сентября 2010

То, что вы ищете, - это символьные вычисления (MATLAB и другие инструменты, используемые в математике и инженерном деле, хороши в этом).

Если вы хотите использовать язык общего назначения, я думаю, что дерево выражений в C # - это хорошая точканачать с.По сути, способность сохранять выражение (вместо оценки выражения в реальных значениях) является ключом для выполнения символьных вычислений.Обратите внимание, что дерево выражений не обеспечивает символьные вычисления, оно просто предоставляет структуру данных, которая поддерживает символьные вычисления.

0 голосов
/ 17 сентября 2010

Схема определяет рациональные числа, числовые значения, числа с плавающей запятой и комплексные числа.Реализация не обязана поддерживать их всех, но если они присутствуют, вы можете смешать их, и они будут «правильными».

0 голосов
/ 17 сентября 2010

Чтобы покрыть реальные числа любым талантом, вам понадобится символический пакет.

Boost, проект C ++, имеет библиотеку Rational , но это только часть истории.

У вас есть иррациональные числа во всех видах форм (пи, основание натурального логарифма, квадратные и кубические корни, константа Champernowne и многие другие).Единственный известный мне способ обработки арифметических операций - это символический пакет со смартами в отношении взаимосвязи между всеми этими числами.Предполагая, что вы можете выразить e ^ pi, как бы вы добавили один к нему?Или взять квадратный корень из этого?

Mathematica может обработать эти случаи.

0 голосов
/ 17 сентября 2010

РЕДАКТИРОВАТЬ: произвольная точность десятичной типы данных не то, что я ищу за. Я хочу иметь возможность представлять числа как 1/3, sqrt (3) или 1 + 2i а также.

В Ruby есть класс Rational, поэтому 1/3 можно выразить в точности как Rational (1,3). Он также имеет сложный класс.

0 голосов
/ 17 сентября 2010

Хотя это не «встроенный», я думаю, C ++ (может быть, C #) ваш лучший выбор. Есть классы, которые были написаны для этой цели.

http://www.oonumerics.org/oon/

0 голосов
/ 17 сентября 2010

Ada изначально поддерживает математику с фиксированной запятой , а также с плавающей запятой. Фиксированная точка может быть намного более точной, чем с плавающей точкой, если показатели числа остаются в диапазоне.

Если вам нужны числа с плавающей запятой, но с большей точностью, чем дает IEEE, существуют пакеты bignum практически для каждого языка.

Я думаю, это лучшее из того, что ты можешь сделать. Ни одна из схем не может точно представлять повторяющиеся десятичные дроби (например, 1/3). Вероятно, было бы возможно придумать такую ​​схему, но я не знаю ни одного языка, который бы поддерживал такую ​​вещь со встроенным типом. Даже это не поможет вам с иррациональными числами (такими как пи и е). Я верю, что есть даже теорема, которая гласит, что всегда будут непредставимые числа, независимо от того, какую схему вы придумали.

...