2016-07-07 2 views
0

У меня нет большого опыта работы с C++, у меня есть следующая проблема. С помощью следующего кода:Как назначить точное содержимое строки для double в C++

double d = 0.0000000; 
stringstream ss; 
ss << std::fixed << std::setprecision(2) << d; 
ss >> d; 

или

std::string content = ss.str(); 
d = atof(content.c_str() ); 

любой из этих двух способов, в то время отладки в MS Visual Studio, я вижу значение D является 0.0000000 не 0.00, как в строке content

Как получить точное содержимое строки, назначенной двойному d?

Может быть, я должен задать более широкий вопрос:

Я пишу метод, который возвращает двойной с точностью по мере необходимости. Например, если у меня есть 2.446343434 как значение d, а точность равна 2, как я могу получить мой метод return d как 2.45?

После прочтения нижеследующих ответов: Я узнал, что это невозможно сделать. Итак, следующий вопрос:

Даже если мой выше код пытается поставить 2.45 в double, среда выполнения C++ добавит нули (сколько?) До 2.45 и вернется вправо? Есть ли способ контролировать добавление нулей в double?

+2

Вы не можете этого сделать, потому что точность 'double' фиксируется компилятором, а' double' имеет ошибки с плавающей запятой. Используйте строку для хранения точного содержимого строки. – MikeCAT

+4

Я не уверен, что ошибки с плавающей запятой имеют к этому какое-то отношение. Как и в случае с реальными числами, нет разницы между 0, 0.00 или 0.0000000 с числами с плавающей запятой. (хотя, в отличие от действительных чисел, существует различие между 0 и -0). –

+1

В чем проблема? Почему вы хотите контролировать точность, которую использует отладчик Visual Studio для отображения значения типа 'double'? –

ответ

7

Я вижу значение г составляет 0,0000000 не 0,00, как и в строке

Но оба эти цифры имеют точно такое же значение. Таким образом, число может иметь значение 0.0000000 тогда и только тогда, когда оно также имеет значение 0.00.

Как получить точное содержание строки, назначенной двойному d?

Вы не можете. double представляет собой числовое значение. Он не представляет собой строку символов.

Кроме того, в более общем случае это невозможно, поскольку числа с плавающей запятой не могут представлять все числа, которые могут быть представлены символьной строкой. Но это не проблема с 0, которая действительно представима.

Я пишу метод, который при необходимости возвращает двойной с точностью. Например, если у меня есть 2.446343434 в качестве значения d и точности 2, как я могу получить мой метод возврата й в 2,45

Вы не можете получить ваш метод возвращал двойной со значением 2.45, если только формат double может представлять 2.45. Формат binary64, указанный IEEE 754, не может представлять 2.45. В таком случае лучшее, что вы можете сделать, это вернуть представимое число, самое близкое к числу с двумя значимыми дробными цифрами, что в случае IEEE 754 будет равно 2.45000000000000017763568394003. Программа в вашем вопросе достигает этого.

Если это не то, что вы хотите, то плавающая точка не подходит для вашего прецедента.

+0

Я пишу метод, который при необходимости возвращает двойной с точностью. Например, если у меня есть 2.446343434 как значение d, а точность равна 2, как я могу получить мой метод return d как 2.45? – SomeDude

+0

@svasa см. Редактирование. – user2079303

+0

Спасибо, даже если мой выше код пытается поставить 2.45 в double, среда выполнения C++ добавит нули (сколько?) До 2.45 и вернется вправо? Есть ли способ контролировать добавление нулей в double? – SomeDude

3

читаемый человеком значение для d, что вы видите в отладчике, «0,0000000», это просто представление и довольно спорное в этом. Фактический объект double не сохраняет эту строку, а не ничего с фиксированным числом знаков после запятой.

Его фактическая идентификация на самом низком уровне: (a) в двоичном формате, (b) закодирована в соответствии со спецификацией с плавающей запятой и (c) не имеет значения для ваших целей. Значение ноль; период.

Отладчик просто решил использовать семь знаков после запятой при преобразовании числа в то, что вы можете читать своими глазами и мозгом. При использовании printf или std::cout, чтобы аналогично выводить номер для чтения, вы можете выбрать какой-либо другой формат, если хотите, в том числе формат с двумя десятичными знаками в соответствии с вашим исходным строковым вводом. Это просто разные способы сказать одно и то же.

Не путайте значение с представлением.

Кроме того, ваш настойчивый конкретно два знака после запятой делает меня подозрительным: если вы планируете использовать double хранить валюту, просто не. Тип плавающей точки не подходит для этого.

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