Если правило значащих цифр означает что-то совершенно другое в другой области, продолжайте :-)

ы печатаете двойной поток, чтобы при чтении он не терял точность?

Я пытался:

std::stringstream ss;

double v = 0.1 * 0.1;
ss << std::setprecision(std::numeric_limits<T>::digits10) << v << " ";

double u;
ss >> u;
std::cout << "precision " << ((u == v) ? "retained" : "lost") << std::endl;

Это не сработало, как я ожидал.

Но я могу повысить точность (что меня удивило, так как я думал, что цифры10 - это максимум, который требуется).

ss << std::setprecision(std::numeric_limits<T>::digits10 + 2) << v << " ";
                                                 //    ^^^^^^ +2

Это связано с количеством значащих цифр, и первые две не учитываются в (0,01).

Так кто-нибудь смотрел на точное представление чисел с плавающей точкой? Какое точное магическое заклинание на потоке мне нужно сделать?

После некоторых экспериментов:

Беда была с моей оригинальной версией. После десятичной точки в строке были незначимые цифры, которые влияли на точность.

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

ss << std::scientific
   << std::setprecision(std::numeric_limits<double>::digits10 + 1)
   << v;

Это все еще не объясняет необходимость +1, хотя.

Кроме того, если я распечатываю число с большей точностью, я получаю распечатку с большей точностью!

std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::digits10) << v << "\n";
std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1) << v << "\n";
std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::digits) << v << "\n";

Это приводит к:

1.000000000000000e-02
1.0000000000000002e-02
1.00000000000000019428902930940239457413554200000000000e-02

На основе @Stephen Canon ответ ниже:

Мы можем точно распечатать, используя форматтер printf (), «% a» или «% A». Для достижения этого в C ++ нам нужно использовать фиксированные и научные манипуляторы (см. N3225: 22.4.2.2.2p5 Таблица 88).

std::cout.flags(std::ios_base::fixed | std::ios_base::scientific);
std::cout << v;

На данный момент я определил:

template<typename T>
std::ostream& precise(std::ostream& stream)
{
    std::cout.flags(std::ios_base::fixed | std::ios_base::scientific);
    return stream;
}

std::ostream& preciselngd(std::ostream& stream){ return precise<long double>(stream);}
std::ostream& precisedbl(std::ostream& stream) { return precise<double>(stream);}
std::ostream& preciseflt(std::ostream& stream) { return precise<float>(stream);}

Далее: Как мы справляемся с NaN / Inf?

Ответы на вопрос(6)

Ваш ответ на вопрос