2015-11-22 7 views
4

Я использую Visual Studio 2015 для печати два плавающих чисел:станд :: соиЬ с плавающей

double d1 = 1.5; 
double d2 = 123456.789; 

std::cout << "value1: " << d1 << std::endl; 
std::cout << "value2: " << d2 << std::endl; 

std::cout << "maximum number of significant decimal digits (value1): " << -std::log10(std::nextafter(d1, std::numeric_limits<double>::max()) - d1) << std::endl; 
std::cout << "maximum number of significant decimal digits (value2): " << -std::log10(std::nextafter(d2, std::numeric_limits<double>::max()) - d2) << std::endl; 

Это печатает следующее:

value1: 1.5 
value2: 123457 
maximum number of significant decimal digits (value1): 15.6536 
maximum number of significant decimal digits (value2): 10.8371 

Почему 123457 это распечатать для значения 123456.789 ? Является ли спецификация ANSI C++ отображать что-либо для плавающих чисел, когда std :: cout используется без std :: setprecision()?

+3

«Имеет ли спецификация ANSI C++ возможность отображать что-либо для плавающих чисел, когда std :: cout используется без std :: setprecision()?» Да. –

+0

@ Германтас, я имею в виду std :: cout. –

+0

@ Маты, почему спецификация настолько расплывчата на эту тему? Это поможет разработчикам, если спецификация более конкретна (например, напечатайте плавающее число со значительными цифрами). Что-то вроде printf («% .16g \ n», d). –

ответ

1

Округление происходит из-за стандарта C++, который можно увидеть написав std::cout<<std::cout.precision();

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

1

Я думаю, проблема здесь в том, что стандарт C++ не написан, чтобы его было легко читать, оно написано, чтобы быть точным и не повторяться. Так что, если вы посмотрите на operator<<(double), это ничего, кроме «не говорят, что это использует num_put - потому что, как cout << some_float_value реализуется

поведение по умолчанию является то, что print("%g", value); делает [таблица 88 в n3337 версии C++. стандарт объясняет, что эквивалентности Printf и C++ форматирования]. Так что если вы хотите сделать %.16g вам нужно изменить точность по телефону setprecision(16).

0

То, что вы указали на самом деле один из тех многих вещей, что комитет по стандартизации следует рассмотреть вопрос о standard iostream на C++. Такие вещи хорошо работают при написании: -

printf ("%f\n", d2); 

Но не с std::cout, где вам нужно использовать std::setprecision, потому что это форматирование аналогично использованию %g вместо %f в printf. Таким образом, вы должны написать: -

std::cout << std::setprecision(10) << "value2: " << d2 << std::endl; 

Но если вы не любите этот метод & используете C++ 11 (& далее), то вы можете также написать: -

std::cout << "value2: " << std::to_string(d2) << std::endl; 

Это даст вам тот же результат, что и printf ("%f\n", d2);.

Гораздо лучший метод, чтобы отменить округление, что происходит в std::cout с помощью std::fixed: -

#include <iostream> 
#include <iomanip> 
int main() 
{ 
    std::cout << std::fixed; 
    double d = 123456.789; 
    std::cout << d; 
    return 0; 
} 

Выход: -

123456.789000 

Так что я думаю, ваша проблема решена !!

+0

Вправо, printf ("% f", d) отображает плавающее число с шестью десятичными цифрами. std :: cout отображает плавающее число с максимум 6 цифрами (включая цифры до и после десятичной точки). Я был смущен, так как не знал об этой точности по умолчанию. Теперь все понятно ... Спасибо. –

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