Все новые проекты рекомендуется использоватьУмножение..
Начало. Многоточная библиотека может использоваться для вычислений, требующих точности, превышающей точность стандартных встроенных типов, таких как плавающий, двойной и длинный двойной. Для более точных расчетов, Boost. Multiprecision предоставляет шаблонный тип данных, называемый cpp_dec_float. Число десятичных цифр точности фиксируется во время компиляции через параметр шаблона.
Чтобы использовать эти типы и константы с плавающей запятой, нам нужны следующие:
#include <boost/math/constants/constants.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
#include <limits>
Итак, теперь мы можем продемонстрировать с некоторыми тривиальными расчетами:
int main()
{
Использование<typedefcpp_dec_float_50
>скрывает сложность многоточности, что позволяет нам определять переменные с точностью до 50 десятичных цифр, как и встроенные<double
>.
using boost::multiprecision::cpp_dec_float_50;
cpp_dec_float_50 seventh = cpp_dec_float_50(1) / 7;
По умолчанию на выходе будут отображаться только стандартные 6 десятичных цифр, поэтому установите точность, чтобы показать все 50 значимых цифр.
std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10);
std::cout << seventh << std::endl;
который выдает:
0.14285714285714285714285714285714285714285714285714
Мы также можем использовать константы, которые гарантированно будут инициализированы с самой последней точностью.
cpp_dec_float_50 circumference = boost::math::constants::pi<cpp_dec_float_50>() * 2 * seventh;
std::cout << circumference << std::endl;
какие выходы
0.89759790102565521098932668093700082405633411410717
Начало. Многоточная библиотека может использоваться для вычислений, требующих точности, превышающей точность стандартных встроенных типов, таких как<float
>,<double
>и<long
double
>. Для более точных расчетов, Boost. Многоточность обеспечивает тип данных шаблона, называемый<cpp_dec_float
>. Число десятичных цифр точности фиксируется во время компиляции через параметр шаблона.
Чтобы использовать эти типы и константы с плавающей запятой, нам нужны следующие:
#include <boost/math/constants/constants.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
#include <limits>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <iterator>
#include <fstream>
Определите текстовую строку, которая является комментарием C++ с лицензией программы, авторским правом и т. Д. Конечно, вы можете адаптировать это к вашим потребностям, в том числе к вашим требованиям об авторском праве. Есть версии<array
>, предоставленные Boost. Array в<boost::array
>или C++11 std::array, но поскольку не все платформы обеспечивают поддержку C++11, эта программа предоставляет версию Boost в качестве запасного варианта.
static const char* prolog =
{
"// Use, modification and distribution are subject to the\n"
"// Boost Software License, Version 1.0.\n"
"// (See accompanying file LICENSE_1_0.txt\n"
"// or copy at ""http://www.boost.org/LICENSE_1_0.txt)\n\n"
"// Copyright ???? 2013.\n\n"
"// Use boost/array if std::array (C++11 feature) is not available.\n"
"#ifdef BOOST_NO_CXX11_HDR_ARRAY\n"
"#include <boost/array/array.hpp>\n"
"#else\n"
"#include <array>\n"
"#endif\n\n"
};
using boost::multiprecision::cpp_dec_float_50;
using boost::math::constants::pi;
int main()
{
Часто приходится вычислять таблицы чисел в математическом программном обеспечении.
Быстрое преобразование Фурье (FFT), например, может использовать таблицу значений греха ((π/2n) в деталях его реализации. Чтобы максимизировать точность в реализации FFT, точность табличных тригонометрических значений должна превышать точность встроенного типа с плавающей запятой, используемого в FFT.
Образец ниже вычисляет таблицу значений греха (π/2n) в диапазоне 1<= n<= 31.
Эта программа использует, среди других элементов программы, тип данных<boost::multiprecision::cpp_dec_float_50
>для точности 50 десятичных цифр от Boost. Многоточность, значение константы π извлечено из Boost. Математика, гарантированно инициализированная с самой последней точностью для типа, здесь<cpp_dec_float_50
>и функция лямбда C++11 в сочетании с<std::for_each()
>.
Определите количество значений в массиве.
std::size_t size = 32U;
cpp_dec_float_50 p = pi<cpp_dec_float_50>();
cpp_dec_float_50 p2 = boost::math::constants::pi<cpp_dec_float_50>();
std::vector <cpp_dec_float_50> sin_values (size);
unsigned n = 1U;
std::for_each
(
sin_values.begin (),
sin_values.end (),
[&n](cpp_dec_float_50& y)
{
y = sin( pi<cpp_dec_float_50>() / pow(cpp_dec_float_50 (2), n));
++n;
}
);
Определите тип плавающей точки для сгенерированного файла, либо встроенного<double,
>флоата, либо<longdouble
>, либо определенного пользователем типа<cpp_dec_float_50
>.
std::string fp_type = "double";
std::cout << "Generating an `std::array` or `boost::array` for floating-point type: "
<< fp_type << ". " << std::endl;
По умолчанию на выходе будут отображаться только стандартные 6 десятичных цифр, поэтому установите точность, чтобы показать достаточно значительные цифры для выбранного типа с плавающей запятой. Для<cpp_dec_float_50
>это 50. (50 десятичных знаков должно быть достаточно для большинства приложений).
std::streamsize precision = std::numeric_limits<cpp_dec_float_50>::digits10;
std::cout << precision << " decimal digits precision. " << std::endl;
Конечно, можно было бы также выбрать меньше, например, 36 было бы достаточно для самых точных текущих<long
double
>реализаций с использованием 128-битных. В общем, это должна быть пара десятичных цифр больше (защитных цифр), чем<std::numeric_limits<RealType>::max_digits10
>для системы-мишени типа с плавающей запятой. Если реализация не предусматривает<max_digits10
>, то вместо этого может использоваться формула Кахана<std::numeric_limits<RealType>::digits
*3010/10000+
2
>.
Компилятор будет читать эти значения в виде десятичных цифр строк и использовать ближайшее представление для типа с плавающей точкой.
Теперь выведите всю синусовую таблицу в файл выбранного вами имени.
const char sines_name[] = "sines.hpp";
std::ofstream fout(sines_name, std::ios_base::out);
if (fout.is_open() == false)
{
std::cout << "Open file " << sines_name << " failed!" << std::endl;
return EXIT_FAILURE;
}
else
{
std::cout << "Open file " << sines_name << " for output OK." << std::endl;
fout << prolog << "// Table of " << sin_values.size() << " values with "
<< precision << " decimal digits precision,\n"
"// generated by program fft_sines_table.cpp.\n" << std::endl;
fout <<
"#ifdef BOOST_NO_CXX11_HDR_ARRAY""\n"
" static const boost::array<double, " << size << "> sines =\n"
"#else""\n"
" static const std::array<double, " << size << "> sines =\n"
"#endif""\n"
"{{\n";
fout.precision(precision);
for (unsigned int i = 0U; ;)
{
fout << " " << sin_values[i];
if (i == sin_values.size()-1)
{
fout << "\n}};\n";
break;
}
else
{
fout << ",\n";
i++;
}
}
fout.close();
std::cout << "Close file " << sines_name << " for output OK." << std::endl;
}
Файл вывода можно увидеть по адресу../../example/sines.hpp
Результат таблицы:
The printed table is:
1
0.70710678118654752440084436210484903928483593768847
0.38268343236508977172845998403039886676134456248563
0.19509032201612826784828486847702224092769161775195
0.098017140329560601994195563888641845861136673167501
0.049067674327418014254954976942682658314745363025753
0.024541228522912288031734529459282925065466119239451
0.012271538285719926079408261951003212140372319591769
0.0061358846491544753596402345903725809170578863173913
0.003067956762965976270145365490919842518944610213452
0.0015339801862847656123036971502640790799548645752374
0.00076699031874270452693856835794857664314091945206328
0.00038349518757139558907246168118138126339502603496474
0.00019174759731070330743990956198900093346887403385916
9.5873799095977345870517210976476351187065612851145e-05
4.7936899603066884549003990494658872746866687685767e-05
2.3968449808418218729186577165021820094761474895673e-05
1.1984224905069706421521561596988984804731977538387e-05
5.9921124526424278428797118088908617299871778780951e-06
2.9960562263346607504548128083570598118251878683408e-06
1.4980281131690112288542788461553611206917585861527e-06
7.4901405658471572113049856673065563715595930217207e-07
3.7450702829238412390316917908463317739740476297248e-07
1.8725351414619534486882457659356361712045272098287e-07
9.3626757073098082799067286680885620193236507169473e-08
4.681337853654909269511551813854009695950362701667e-08
2.3406689268274552759505493419034844037886207223779e-08
1.1703344634137277181246213503238103798093456639976e-08
5.8516723170686386908097901008341396943900085051757e-09
2.9258361585343193579282304690689559020175857150074e-09
1.4629180792671596805295321618659637103742615227834e-09
*/
Выход может быть скопирован в виде текста и легко интегрирован в данный исходный код. Альтернативно, выход может быть записан в текст или даже использоваться в самописном автоматическом генераторе кода в качестве примера.
Для проверки результатов, полученных от Boost, может использоваться компьютерная система алгебры. Математика и рост. Многоточность. Например, компьютерная алгебраWolfram Mathematicaможет получить аналогичную таблицу с командой:
Table[N[Sin[Pi / (2^n)], 50], {n, 1, 31, 1}]
Для создания этой таблицы можно также использовать механизм вычислительных знанийWolfram Alpha. Та же команда может быть вставлена в вычислительное поле.