Класс с нулевым округлением в .Net? - PullRequest
2 голосов
/ 28 октября 2011

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

Например, это не то, что я хочу:

decimal dividend = Decimal.One;
decimal divisor = 3;
dividend/divisor * divisor // gives us 0.9999999999999999999999999999 instead of 1

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

Num n = new Num(1);
n.DivideBy(3);
n.MultiplyBy(3);
n.toString(); // gives us "1"

Num n2 = new Num(n);
n2.DivideBy(3);
int decimal_places = 8;
n2.RoundHalfUp(decimal_places);
n2.toString(); // gives us "0.33333333"

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

Я понимаю, что производительность будет ниже, чем Double или Decimal. Но он не должен делать вычисления вслепую, если он находится в пределах приемлемого времени.

Ответы [ 3 ]

7 голосов
/ 28 октября 2011

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

Если вам нужно вычислить произвольные непрерывные функции (например, логарифмы, косинусы, квадратные корни и т. Д.), Оно становится способ более сложным.Отслеживание необходимых цифр для обеспечения требуемой точности является сложным, но, безусловно, выполнимым, хотя и неэффективным на практике.Идея состоит в том, чтобы хранить вдоль каждой функции другую функцию, вычисляющую модуль непрерывности (вы получите то, что можно было бы назвать « интуиционистские непрерывные функции»).дерево выражений не сильно упрощает вопросы, так как вам нужно оценить результирующее (мы надеемся, более простое) выражение.

Другой подход - сохранить ряд степеней вместе с радиусом сходимости и вычислитьсумма серии по запросу.

1 голос
/ 28 октября 2011

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

Но если вы хотите решить общую проблему, чтобы Math.Pow(Math.Sqrt(2), 2) == 2 возвращал true и это работало для произвольных операций, вам понадобится тип, который может представлять любые вычисления и иметь возможность надежно их упростить. Недостаточно просто отложить расчет.

Я не уверен, что что-то подобное существует или даже возможно.

0 голосов
/ 28 октября 2011

Возможно, вам понадобится целочисленная библиотека произвольной точности для ваших нужд?

Связанный ответ имеет дело с C #, но, конечно, это действительно общие ответы .NET.

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