Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Examples

Boost , Math Toolkit 2.5.0 , Facets for Floating-Point Infinities and NaNs

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext
Simple example with std::stringstreams
locale old_locale;
locale tmp_locale(old_locale, new nonfinite_num_put<char>);
locale new_locale(tmp_locale, new nonfinite_num_get<char>);
stringstream ss;
ss.imbue(new_locale);
double inf = numeric_limits<double>::infinity();
ss << inf; // Write out.
assert(ss.str() == "inf");
double r;
ss >> r; // Read back in.
assert(inf == r); // Confirms that the double values really are identical.
cout << "infinity output was " << ss.str() << endl;
cout << "infinity input was " << r << endl;
// But the string representation of r displayed will be the native type
// because, when it was constructed, cout had NOT been imbued
// with the new locale containing the nonfinite_numput facet.
// So the cout output will be "1.#INF on MS platforms
// and may be "inf" or other string representation on other platforms.
Use with lexical_cast
[Note] Note

Начиная с Boost 1.48, lexical_cast больше не использует струнные потоки внутри, и теперь может обрабатывать бесконечности и NaN на большинстве платформ.

Без использования новой локации, содержащей неконечные грани, предыдущие версии<lexical_cast>с использованием струнного потока не были переносимы (и часто терпели неудачу), если были найдены неконечные значения.

locale old_locale;
locale tmp_locale(old_locale, new nonfinite_num_put<char>);
locale new_locale(tmp_locale, new nonfinite_num_get<char>);

Хотя другие примеры наполняют отдельные потоки новой локализацией, для потоков, построенных внутри lexical_cast, было необходимо назначить глобальную локализацию.

locale::global(new_locale);

<lexical_cast>Тогда работает как ожидалось, даже с бесконечностью и NaNs.

double x = boost::lexical_cast<double>("inf");
assert(x == std::numeric:limits<double>::infinity());
string s = boost::lexical_cast<string>(numeric_limits<double>::infinity());
assert(s == "inf");
[Warning] Warning

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

[Warning] Warning

Вы должны знать, что спецификация C++ явно не требует, чтобы ввод от десятичных цифр строк преобразовывался округлением до ближайшего представляемого двоичного значения с плавающей точкой. (В противоположность этому десятичные цифры, считываемые компилятором, например, назначением, подобным<double d= 1.234567890123456789>, гарантированно присваивают ближайшему репрезентабельному значению удвоение d). Это означает, что независимо от того, сколько десятичных цифр вы предоставляете, существует потенциальная неопределенность в 1 наименее значимый бит в результирующей двоичной величине.

См.преобразование и округлениедля получения дополнительной информации оближайших репрезентабельныхиокруглениеиИзучение двоичныхдля получения подробной информации о входе и затруднениях округления.

Большинство библиотек iostream действительно достигают желаемогоближайшего представляемого двоичного значения с плавающей точкойдля всех значений ввода. Однако одна популярная библиотека STL не совсем добивается этого для 64-битных двойников. Видишь?Десятизначный ввод строки для удвоения может быть 1 бит неправильнодля причудливых полных деталей.

Если вы ожидаете совершить кругосветное путешествие<lexical_cast>или<serialization>, например, архивирование и загрузку, и хотите быть абсолютно уверены, что вы всегда получите точно идентичную двоичную модель с двойным значением, вы должны использовать предлагаемый обход, который, как считается, работает на всех платформах.

Вы должны вывести все потенциально значимые десятичные цифры, установив точность потока до<std::numeric_limits<double>::max_digits10>(или для соответствующего типа с плавающей запятой, если не двойной) и, что важно,требуют<scientific>формата, а не<fixed>или автоматического (по умолчанию), например:

double output_value = any value;
std::stringstream s;
s << setprecison(std::numeric_limits<double>::max_digits10) << scientific << output_value;
s >> input_value;
Use with serialization archives

Важно, чтобы одна и та же область использовалась при сохранении архива и его загрузке. В противном случае загрузка архива может выйти из строя. По умолчанию архивы сохраняются и загружаются с помощью классического C-локала с добавлением<boost::archive::codecvt_null>граней. Обычно вам не нужно беспокоиться об этом.

Конструкторы для архивных классов, как побочный эффект, пропитывают поток такой локализацией. Однако если вы хотите использовать грани<nonfinite_num_put>и<nonfinite_num_get>с архивами, то вам придется управлять локализацией вручную. Это делается путем вызова архивостроителя с флагом<boost::archive::no_codecvt>, тем самым гарантируя, что архивостроительне наполнит поток новой локацией.

Следующий код показывает, как использовать<nonfinite_num_put>с<text_oarchive>.

locale default_locale(locale::classic(), new boost::archive::codecvt_null<char>);
locale my_locale(default_locale, new nonfinite_num_put<char>);
ofstream ofs("test.txt");
ofs.imbue(my_locale);
boost::archive::text_oarchive oa(ofs, no_codecvt);
double x = numeric_limits<double>::infinity();
oa & x;

Этот же метод работает с<nonfinite_num_get>и<text_iarchive>.

Если вы используете<nonfinite_num_put>с<trap_infinity>и/или<trap_nan>флагом с архивом сериализации, то вы должны установить маску исключения потока. Архивы сериализации не проверяют состояние потока.

Other examples

nonfinite_facet_simple.cppдает несколько более простых демонстраций разницы между использованием классического C locale и построением C99 infinty и NaN-совместимого locale для ввода и вывода.

См.nonfinite_facet_sstream.cppдля этого примера использования с<std::stringstream>s.

Пример того, как обеспечить реализацию представлений MSVC "legacy" "1.#INF" и "1.#QNAN" для ввода и вывода см.nonfinite_legacy.cpp.

Обработка сигналов NaN показана на../../пример/nonfinite_signaling_NaN.cpp

Пример../../example/nonfinite_loopback_ok.cppпоказывает, что обратная связь работает нормально.

Пример../../example/nonfinite_num_facet.cppпоказывает выход и повторный ввод различных конечных и неконечных значений.

Простым примером улавливания неконечного вывода являетсяnonfinite_num_facet_trap.cpp.

Яркий пример использования Boost. Архив находится по адресу../../example/nonfinite_serialization_archives.cpp.

Полная демонстрация сериализации Франсуа Могера на../../пример/nonfinite_num_facet_serialization.cpp


PrevUpHomeNext

Статья Examples раздела Math Toolkit 2.5.0 Facets for Floating-Point Infinities and NaNs может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Facets for Floating-Point Infinities and NaNs ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 04:52:58/0.0073251724243164/1