с плавающей точкой — установить обратно точность по умолчанию Переполнение стека

Я хочу контролировать точность для double во время сравнения, а затем вернуться к точности по умолчанию с помощью C ++.

Я намерен использовать setPrecision() установить точность. Каков тогда синтаксис, если таковой имеется, чтобы вернуть точность к значению по умолчанию?

Я делаю что-то подобное

std::setPrecision(math.log10(m_FTOL));

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

Я изменил, как это, и у меня все еще есть некоторые ошибки

std::streamsize prec = std::ios_base::precision();
std::setprecision(cmath::log10(m_FTOL));

с cmath ложь при компиляции и std::ios_base также ложно при компиляции. Не могли бы вы помочь?

Благодарю.

14

Решение

Вы можете получить точность до Вы меняете это, с std::ios_base::precision и затем используйте это, чтобы изменить это позже.

Вы можете увидеть это в действии с:

#include <ios>
#include <iostream>
#include <iomanip>

int main (void) {
double d = 3.141592653589;
std::streamsize ss = std::cout.precision();
std::cout << "Initial precision = " << ss << '\n';

std::cout << "Value = " << d << '\n';

std::cout.precision (10);
std::cout << "Longer value = " << d << '\n';

std::cout.precision (ss);
std::cout << "Original value = " << d << '\n';

std::cout << "Longer and original value = "<< std::setprecision(10) << d << ' '
<< std::setprecision(ss) << d << '\n';

std::cout << "Original value = " << d << '\n';

return 0;
}

какие выводы:

Initial precision = 6
Value = 3.14159
Longer value = 3.141592654
Original value = 3.14159
Longer and original value = 3.141592654 3.14159
Original value = 3.14159

Код выше показывает два способа установки точности, во-первых, вызывая std::cout.precision (N) а во-вторых, используя потоковый манипулятор std::setprecision(N),


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

if (val1== val2) ...

Другими словами, хотя выход может быть 3.14159само значение все еще полное 3.141592653590 (с учетом нормальных ограничений с плавающей запятой, конечно).

Если вы хотите сделать это, вам нужно проверить, достаточно ли оно близко, а не равно, с помощью кода, такого как:

if ((fabs (val1 - val2) < 0.0001) ...
23

Другие решения

Вам необходимо отслеживать текущую прецизионность, а затем возвращаться к той же величине, как только вы выполняете операции с необходимой измененной прецессией. Для этого вы можете использовать станд :: ios_base :: точность:

streamsize precision ( ) const;
streamsize precision ( streamsize prec );

Первый синтаксис возвращает значение текущего поля точности с плавающей точкой для потока.
Второй синтаксис также устанавливает его в новое значение.

4

setprecision () может использоваться только для операций вывода и не может использоваться для сравнения

Чтобы сравнить числа с плавающей точкой, скажем, a и b, вы должны сделать это явно так:

  if( abs(a-b) < 1e-6) {
}
else {
}
2

Сохранить все состояние с std::ios::copyfmt

Вы также можете восстановить все предыдущее состояние с помощью std::ios::copyfmt в этих ситуациях, как объяснено на: Восстановите состояние std :: cout после манипулирования им

main.cpp

#include <iomanip>
#include <iostream>

int main() {
constexpr float pi = 3.14159265359;
constexpr float e  = 2.71828182846;

// Sanity check default print.
std::cout << pi << std::endl;
std::cout << e  << std::endl;

// Change precision and restore default afterwards.
std::ios cout_state(nullptr);
cout_state.copyfmt(std::cout);
std::cout << std::setprecision(10);
std::cout << pi << std::endl;
std::cout << e  << std::endl;
std::cout.copyfmt(cout_state);

// Check that cout state was restored.
std::cout << pi << std::endl;
std::cout << e  << std::endl;
}

Скомпилируйте и запустите:

g++ -o main.out -std=c++11 main.cpp
./main.out

Выход:

3.14159
2.71828
3.141592741
2.718281746
3.14159
2.71828

Протестировано на Ubuntu 16.04, GCC 6.4.0.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector