2017-02-22 116 views
1

Мы не можем хранить десятичное число в бесконечной точности, но может быть какой-то способ представить их так же, как мы представляем бесконечные списки в haskell.Есть ли идея решить проблему с плавающей точкой в ​​будущем?

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

Но есть некоторые очевидные проблемы, думать о количестве a = 0.333... и b = 0.666..., если мы плюс их вместе, мы получили ans = 0.999... (последовательность цифр), но мы никогда не можем сказать, является ли a + b == 1 в этом случае.

То, что я хочу, чтобы определить десятичное число как-то, так что он не поддерживает +, -, *, /, >, == операции, и независимо от того, что +, -, *, / операцию мы применили к ним десятичные числа, мы получаем новые десятичные числа, которые мы можем вычислить с точностью до k цифр при любом натуральном k.

Мне интересно: есть ли какие-либо идеи, которые могут это решить?

+1

Вы видели http://hackage.haskell.org/package/cyclotomic? – jkeuhlen

+3

Я не уверен, что ваши требования четко определены. Возможно, «Рациональный» - это то, что вы ищете; он поддерживает все эти операции без потери точности (вы не сможете построить с ними иррациональное число) – jberryman

+2

В более общем плане вы никогда не сможете «x == y», потому что независимо от того, сколько цифр вы вычисляете, вы никогда не сможете быть уверены что следующий не будет отличаться. По-видимому, практическое решение состоит в том, чтобы иметь семьи чисел, чтобы программисты могли выбрать тот, который им нужен. –

ответ

5

Haskell предлагает Rational, Cyclotomic и CReal для выполнения точной арифметики.

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

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

Rational представляет все числа, которые могут быть записаны как фракции. Это значительно меньший кусок реалов, чем CReal или Cyclotomic: квадратные корни (и другие корни) в значительной степени выходят из строя, тригонометрические функции почти не выходят, pi и e выходят и т. Д. Но наблюдения соответственно более эффективны, чем для CReal и Cyclotomic, поэтому они иногда просто билет.

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

+1

Где (т. Е. В пакете Hackage) этот тип «CReal», который представляет [вычислимые реалы] (https://en.wikipedia.org/wiki/Computable_number)? Возможно, вы имели в виду [конструктивный] (https://hackage.haskell.org/package/numbers-3000.2.0.1/docs/Data-Number-CReal.html#t:CReal)? (Отличный ответ, мне просто любопытно, есть ли известная реализация Haskell вычислимых реалов, о которой мне все время не удалось узнать ...) – user2407038

+0

@ user2407038 Насколько я знаю, «конструктивные переменные» является синонимом «вычислимых реалов». –

+0

Я понимаю, что «конструктивные» реалы обладают свойством «зная наверняка, что первая цифра должна быть [технически неразрешимой» (как вы сказали в ответе), по крайней мере, для произвольного конструктивного реального, но «вычислимые» свойство «мы можем вычислить их точными до k цифр при любом натуральном k». (как указано в ОП). Конструктивные переменные представляют собой фактический набор реалов, тогда как вычислимые реалы являются всего лишь (плотным) подмножеством вещественных чисел. Эти две разные, но я не уверен, какому из них соответствует «data CReal = CR (Int -> Integer)». – user2407038