2012-03-20 2 views
2

Я вычисляю pi, используя длинную формулу. Я пытаюсь получить больше знакомы с числами с плавающей запятой и т. Д. У меня есть рабочая программа, которая использует удвоения. Проблема с моим кодом:Использование длинного двойного или просто двойного для вычисления pi?

  1. Если я использую double, pi только точный до 7-го знака после запятой. Я не могу понять, что это более точно.
  2. Если я использую длинный двойник, то pi точнее вплоть до девятого десятичного разряда, однако код занимает намного больше времени для запуска. Если я проверяю точность менее 0,00000001 с использованием длинного двойника, pi возвращает значение 9.4246775. Я предполагаю, что это связано с длинным удвоением.

Мой вопрос - это самый точный тип переменной? Как я могу изменить свой код, чтобы улучшить точность pi?

Вот мой код:

#include <iomanip> 
#include <cstdlib> 
#include <iostream> 
#include <cmath> 

using namespace std; 

int main() 
{ 
double arctan; 
double pi; 
double precision; 
double previous=0; 
int y=3; 
int loopcount=0; 

    cout<<"Start\n"; 

    arctan=1-(pow(1,y)/y); 

do 
    { 
    y=y+2; 
    arctan=arctan+(pow(1,y)/y); 
    y=y+2; 
    arctan=arctan-(pow(1,y)/y); 

     pi=4*(arctan); 

    // cout<<"Pi is: "; 
    // cout<<setprecision(12)<<pi<<endl; 

     precision=(pi*(pow(10,10)/10)); 

     loopcount++; 

     if(precision-previous<0.000000001) 
     break; 

     previous=precision; 
    } 
    while(true); 

    cout<<"Pi is:"<<endl; 
     cout<<setprecision(11)<<pi<<endl; 
    cout<<"Times looped:"<<endl; 
     cout<<loopcount<<endl; 

return 0; 
} 
+1

Вам следует рассмотреть возможность переключения на представление с фиксированной точкой, если вы хотите жестко контролировать точность. –

+2

Когда вы изменили на 'long double', вы изменили _all_ вызовы API, например. 'pow()' to 'powl()', 'arctan()' в 'atanl()' -эквивалент и т. д.? – sarnold

+0

Дуг, не могли бы вы объяснить это? Я не знаком с этим. – adohertyd

ответ

3

Вы можете получить максимальные пределы двойников/длинных дублей от StD :: numeric_limits

#include <iostream> 
#include <limits> 

int main() 
{ 
    std::cout << "  Double::digits10: " << std::numeric_limits<double>::digits10 << "\n"; 
    std::cout << "Long Double::digits10: " << std::numeric_limits<long double>::digits10 << "\n"; 
} 

На моей машине это дает:

 Double::digits10: 15 
Long Double::digits10: 18 

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

http://www.cplusplus.com/reference/std/limits/numeric_limits/

Стандартная цитата: 18.3.2 Numeric limits [limits]

Также Примечание: Как комментарий является путь вниз в приведенном выше списке:

Это @sarnold (хотя загадочно у него есть два глупых человека, которые голосуют без комментариев) в своих утверждениях на pow(). То, что он утверждает, применимо только к C. C++ имеет перегрузки для типов, потому что в C++ pow() является функцией шаблона. См.: http://www.cplusplus.com/reference/clibrary/cmath/pow/ в стандарте: 26.4.7 complex value operations [complex.value.ops]

+0

Это отличный ответ для этого. Не мог видеть ничего об этих ограничениях, и я много читал об этом. Спасибо за четкий ответ. – adohertyd

+0

Быстрый вопрос для вас. Если длинный двойной показатель является точным до 18 мест, почему я получаю значение 9.454665 ... для pi после того, как я меняю уровень точности на <0.000000001? – adohertyd

+0

Каковы значения на вашем компьютере. Эти значения не универсальны. –

1

Заданный тип с плавающей точкой с наибольшей точностью является long double.

Есть три предопределенных типов с плавающей точкой:

  • float имеет по крайней мере 6 десятичных цифр точности
  • double имеет, по меньшей мере, 10, и по крайней мере столько, сколько float
  • long double имеет в не менее 10 и, по меньшей мере, double

Это минимальные требования ц; любой или все из этих типов могут иметь более высокую точность.

Если вам нужна более высокая точность, чем может быть long double, вы можете посмотреть GMP, который поддерживает произвольную точность (при значительных расходах на скорость и использование памяти).

Смежные вопросы