Клас з нульовим округленням-помилкою у .Net?

Привіт усім мені цікаво, чи існує клас в .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 . Але це не треба робити обчислення сліпо швидко, доки він знаходиться в межах прийнятного часу.

2
@RickLiddle Дещо це. Моя вимога полягає в тому, що він "правильно" виконує математику (без помилок округлення) і в межах прийнятного часу. Тому я хотів би розглянути можливість скасування, щоб спростити твердження очевидним вдосконаленням (роблячи це таким чином, як люди це зробили), але не вимогою, якщо він виконує розрахунки протягом прийнятного часу.
додано Автор Pacerier, джерело
Чи є алгебраїчна бібліотека, яка зробить скасування, щоб спростити твердження перед тим, як вирішити, що ви шукаєте? Я не зіткнувся з одним, але якщо це те, що ви після, можливо, хтось має певну інформацію ...
додано Автор Rick Liddle, джерело

3 Відповіді

Це робота для раціональних номерів . Немає необхідності відкладати що-небудь, якщо ви виконуєте лише арифметичні операції (включаючи поділ).

Якщо вам потрібно розрахувати довільні неперервні функції (наприклад, логарифми, косинуси, квадратні коріння тощо), він стає способом більш активним. Відстеження потрібних цифр для забезпечення точності запиту є складним, але безперечно здійсненним, хоча і практичним неефективним. Ідея полягає в тому, щоб зберігати по кожній функції іншу функцію, обчислюючи модуль безперервності (ви отримаєте те, що буде називайте " інтуїціоністські безперервні функції").

Зверніть увагу, що зберігання дерева виразів не полегшує багато чого, тому що вам потрібно буде оцінити отриманий (надіюсь спрощений) вираз.

Інший підхід полягає в тому, щоб зберегти владний ряд разом з радіусом збіжності та обчислювати суму серії за запитом.

7
додано
@AlexandreC Спасибі, це хороший матеріал, я хотів би провести кілька досліджень по посиланням/класу.
додано Автор Pacerier, джерело
Re "Відстеження потрібних цифр, щоб забезпечити запитувану точність": мені здається, що запитана точність нескінченна.
додано Автор svick, джерело
@svick: ідея полягає в тому, що ви тільки запитуєте точність наприкінці обчислення (наприклад, при відображенні номера). На цьому етапі все обчислюється (на своєму шляху зберігається якесь дерево), і необхідні цифри для кожного субразраження обчислюються рекурсивно. Це досить легко реалізувати на функціональних мовах. Номери представлені у вигляді функцій, які приймають ціле число n і повертають раціональний номер у 2 ^ (- n) представленого числа (вони дійсно true реальні цифри!) Той, хто володіє F #, може спробувати.
додано Автор Alexandre C., джерело
Застереження полягає в тому, що рівність невизначена для цих чисел.
додано Автор Alexandre C., джерело
@ Пазерер: якщо ви не проти математики і готові терпіти деякі Haskell, у вас є якийсь ресурс: haskell.org/haskellwiki/Exact_real_arithmetic
додано Автор Alexandre C., джерело

Ваша конкретна проблема може бути вирішена типом, який може точно представляти будь-яку частку. Ви можете використовувати для цього бібліотеку або написати саму (це не повинно бути таким важким).

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

Я не впевнений, що щось подібне існує або що це навіть можливо.

1
додано
Так, ви отримуєте тут пункт, те, що я намагався сказати, це те, що він "не повинен бути дуже розумним", але до тих пір, поки це "як людина", це чудово. (наприклад, людина може легко сказати, що Math.Pow Math.Sqrt скасовується)
додано Автор Pacerier, джерело

Можливо, для ваших потреб буде достатньо цілі бібліотеки довільної точності ?

Пов'язана відповідь стосується C#, але, звичайно, вони є дійсно загальними .NET-відповідями.

0
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug