C # Высокая двойная точность - PullRequest
5 голосов
/ 05 ноября 2010

Я пишу функцию, которая вычисляет значение PI и возвращает его как двойное число. Все идет нормально. Но как только функция доходит до 14 цифр после запятой, она больше не может удерживаться. Я предполагаю, что это из-за ограниченной точности двойника. Что я должен сделать, чтобы продолжить получать больше чисел после запятой?

Ответы [ 6 ]

16 голосов
/ 05 ноября 2010

Я бы не стал делать это с плавающей запятой вообще.

Напомним, что ваш алгоритм:

(1 + 1 / (2 * 1 + 1)) *  
(1 + 2 / (2 * 2 + 1)) *  
(1 + 3 / (2 * 3 + 1)) *  
(1 + 4 / (2 * 4 + 1)) *  
(1 + 5 / (2 * 5 + 1)) *  
(1 + 6 / (2 * 6 + 1)) *  
(1 + 7 / (2 * 7 + 1)) *  ...

На каждом этапе пути вы вычисляете дробь. Почему бы просто не сохранить эту дробь в форме числителя / знаменателя? Фракция, которую вы хотите вычислить:

(4 / 3) * 
(7 / 5) *
(10 / 7) *
(13 / 9) * ...

, что составляет всего 4 * 7 * 10 * 13 ... сверху и 3 * 5 * 7 * 9 снизу.

Получите себе класс BigInteger (поставляется с платформой 4.0 в System.Numerics), и вы можете легко вычислить числитель и знаменатель настолько большого, насколько вам нужно. Тогда у вас просто есть проблема преобразования частного в десятичное. Ну, это достаточно просто. Предположительно вы знаете, как сделать длинное деление . Просто внедрите длинный алгоритм деления на числитель и знаменатель, который выплевывает желаемое количество цифр.

8 голосов
/ 05 ноября 2010

Сколько точности вам нужно?

Использование decimal даст вам примерно 28 знаков после запятой:

decimal pi = 3.14159265358979323846264338327950288419716939937510m;
Console.WriteLine(pi);    // 3.1415926535897932384626433833

Если вам этого недостаточновам нужно будет найти какую-то реализацию BigDecimal или взглянуть на другие методы выполнения вычислений.

1 голос
/ 05 ноября 2010

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

1 голос
/ 05 ноября 2010

Есть несколько библиотек, которые позволяют вам работать с произвольной точностью. Одним из них является W3b.sine , но несколько других описаны в wikipedia .

0 голосов
/ 05 ноября 2010

Вы можете использовать тип J # BigDecimal, как предложено в в этом ответе .

0 голосов
/ 05 ноября 2010

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

...