Arhn - архитектура программирования

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

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

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

EDIT: Типы данных произвольной точности decimal не то, что я ищу. Я также хочу иметь возможность представлять такие числа, как 1/3, sqrt(3) или 1 + 2i.


  • Несколько хороших ответов ниже (и я добавлю, что однажды написал математический пакет для рациональных чисел), но если вы серьезно, у вас есть проблема: вы не можете выразить каждое действительное число (или даже каждое действительное число на [0,1)) в конечном пространстве. Таким образом, есть твердое теоретическое требование, что вы можете получить только реальное сходство. Затем становится вопросом выбора приближения, которое лучше всего соответствует вашим потребностям. 17.09.2010
  • Эээ... что касается редактирования... вам нужны вещественные или комплексные числа? 17.09.2010
  • @dmckee Я знаю об этом. Но можно иметь достаточно хорошие приближения. Все, что они здесь используют, должно работать нормально: wolframalpha.com/index.html 17.09.2010
  • @dmckee Это проскользнуло ... Я тоже хочу мнимые числа. 17.09.2010
  • Я предполагаю, что арифметика действительных чисел не исключает арифметику комплексных чисел (например, 1 + 2i)? 17.09.2010
  • @NUllUser Ну, когда у вас есть реальные числа, которые вам нравятся, вы всегда можете обобщить их на сложную плоскость. 17.09.2010
  • Вы исключаете Mathematica как недостаточно универсальную? 17.09.2010
  • Если вы хотите явно представлять действительные числа, мнимые и комплексные числа, радикалы и иррациональные числа без потери точности, я думаю, что ваш единственный выбор — это система символов, такая как Mathematica (как предложил Джон) или Maple или тому подобное. Если вам необходимо иметь как символьные выражения без потерь, так и средства программирования общего назначения, вы можете запустить сценарий Mathematica или Maple из командной строки какого-либо другого языка. 18.09.2010
  • Просматривая старые закладки, я нашел это: dcs.ed.ac. uk/home/mhe/plume/report.html 20.09.2010

Ответы:


1

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

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

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

Mathematica может справиться с такими случаями.

17.09.2010

2

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

17.09.2010
  • Если вы можете найти компилятор для одной из последних версий стандарта Fortran, это не так уж это отвратительно. 17.09.2010
  • @ТЕД. - Многие компиляторы на рынке имеют большинство; а некоторые (их число увеличивается) имеют все функции F2003. Я вовсе не считаю его древним (по сравнению с массой других языков-компиляторов/интерпретаторов для них). И да, он имеет обширную поддержку ... многих вещей. Тем не менее, если кто-то хочет большего, всегда можно использовать только функции FORTRAN 66 :-) 17.09.2010
  • Это может вызвать флеймовую войну, но Fortran77 на самом деле самая надежная вещь. С его помощью вы пишете короткие и эффективные подпрограммы, а затем вызываете их на честном языке с той же легкостью, что и функции C. Это не так с F90 или несуществующим на практике F2003 (это тот, что с функциями OO?) 17.09.2010
  • @Alexandre C. - Я не уверен, что именно вы имеете в виду, но если кто-то хочет использовать произвольную точность (переносимую), то ему понадобятся функции/компилятор f90/95 (selected_real_kind() и др.). Не могли бы вы уточнить свой комментарий на тот случай, если я неправильно понял его смысл? Тоже по несуществующей на практике части f2003? 17.09.2010
  • @Rook: Действительно ли f90 и f95 поддерживают sqrt (3) и тому подобное? Или 1/3? Прошло очень много времени с тех пор, как я в последний раз использовал Фортран, и это был f77. 17.09.2010
  • @ Дэвид Торнли - ваш вопрос несколько расплывчатый. Да, вы можете возвести в квадрат целое число, но я не думаю, что это то, о чем вы спрашиваете. Возьмите учебник по google-fortran и немного почитайте о KIND и типах данных. Это должно устранить некоторые дилеммы. Я мог бы написать об этом здесь, но это было бы просто переписыванием уже написанного, и, вероятно, в худшую сторону. Да, после f77 в языке в этом сегменте произошли существенные изменения. 18.09.2010

  • 3

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

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

    17.09.2010

    4

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

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

    17.09.2010

    5

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

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

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

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

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

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

    17.09.2010

    6

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

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

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

    17.09.2010

    7

    Ява: java.math.BigDecimal

    C#: decimal

    17.09.2010

    8

    Многие языки поддерживают это: Java имеет BigDecimal, Perl имеет Math::BigFloat и Math::BigRat, Haskell имеет Integer, и многие библиотеки и языки перечислены в википедия.

    17.09.2010
  • Ruby также имеет класс BigDecimal. 17.09.2010

  • 9

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

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

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

    17.09.2010
  • Хорошо, воспользуйся этим, чтобы получить точное значение числа пи, которое я смогу использовать в своих программах. Я подожду здесь. :-) 17.09.2010
  • Не говорю, что они имеют точное значение, я говорю, что это мое определение достаточно хорошего 18.09.2010
  • Хорошо, есть загвоздка: что точно является вашим определением достаточно хорошего? Я никогда не видел, чтобы это было определено, а 64-битные числа с плавающей запятой более чем достаточны почти для всех, кто работает за пределами НАСА. Для всех остальных это то, для чего предназначены пакеты bignum. Совершенство, как сказано в моем ответе, в общем случае недостижимо, 18.09.2010

  • 10

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

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

    17.09.2010
  • Есть и другие языки, такие как Лисп, с рациональными числами и комплексными числами. Нечисловой способ представления квадратного корня из 3 встречается гораздо реже. 17.09.2010

  • 11

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

    17.09.2010

    12

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

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

    17.09.2010
  • Подавляющее большинство числовых библиотек было написано для языков низкого уровня, таких как C и Fortran, а не для языков высокого уровня, таких как C#. 17.09.2010
  • Вы можете с уверенностью сказать, что это возможно сделать на C++ и C#, если вы действительно этого хотите, но лучше всего? Над языками с родной поддержкой таких вещей? Едва. 17.09.2010
  • Хотя, чтобы сыграть роль адвоката дьявола, C# имеет встроенную десятичную систему для более высокой точности: msdn.microsoft.com/en-us/library/364x0z75%28VS.80%29.aspx 17.09.2010
  • @Reinderien: Совершенно очевидно, что то, что хотел ОП, не было чем-то вроде long long double, и я действительно сомневаюсь, что C # поставляется с десятичными знаками бесконечной точности. 17.09.2010
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..