Есть примерно такой код:
double y_min = -7.0;
double y_step = 1.4;
for(int i = 0; i <= 10; ++i)
{
std::ostringstream oss;
oss << (y_min + i*y_step);
...
}
Проблема в том, что при i == 5, в oss в релизе выводится число 8.88178e-16, хотя в дебаге все нормально — выводится 0. (VS 7.1)
В чем дело?
Здравствуйте, Аноним, Вы писали:
А>Есть примерно такой код:
А>А>double y_min = -7.0;
А>double y_step = 1.4;
А>for(int i = 0; i <= 10; ++i)
А>{
А> std::ostringstream oss;
А> oss << (y_min + i*y_step);
А> ...
А>}
А>
А>Проблема в том, что при i == 5, в oss в релизе выводится число 8.88178e-16, хотя в дебаге все нормально — выводится 0. (VS 7.1)
А>В чем дело?
Поищи вопросы на тему сравнения double с нулем. Обсуждалось много раз
Здравствуйте, LuciferMoscow, Вы писали:
LM>Поищи вопросы на тему сравнения double с нулем. Обсуждалось много раз
А как это мне поможет? Мне нужно, чтобы не выводились цифры в 16-м знаке после запятой.
Вместо нуля может быть любое другое число. oss.precision(5) почему-то не помогает.
И почему в дебаге работает?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, LuciferMoscow, Вы писали:
LM>>Поищи вопросы на тему сравнения double с нулем. Обсуждалось много раз
А>А как это мне поможет? Мне нужно, чтобы не выводились цифры в 16-м знаке после запятой.
А>Вместо нуля может быть любое другое число. oss.precision(5) почему-то не помогает.
А ты найди темы и почитай.
А>И почему в дебаге работает?
Потому, что в дебагере он округлил по всей видимости
Здравствуйте, Аноним, Вы писали:
А>Есть примерно такой код:
А>А>double y_min = -7.0;
А>double y_step = 1.4;
А>for(int i = 0; i <= 10; ++i)
А>{
А> std::ostringstream oss;
А> oss << (y_min + i*y_step);
А> ...
А>}
А>
А>Проблема в том, что при i == 5, в oss в релизе выводится число 8.88178e-16, хотя в дебаге все нормально — выводится 0. (VS 7.1)
А>В чем дело?
Это вопрос для общего развития или для решения проблемы?
Если для решения, то смотри форматирование в
stream-ах.
std::ostringstream oss;
oss.setf(ios_base::fixed, ios_base::floatfield);
oss.precision(2);
А причиной может быть оптимизация — попробуй
double volatile y_min = -7.0;
double volatile y_step = 1.4;
...
Здравствуйте, KosTiger, Вы писали:
KT>Это вопрос для общего развития или для решения проблемы?
Для решения проблемы.
KT>Если для решения, то смотри форматирование в stream-ах.
KT>KT> std::ostringstream oss;
KT> oss.setf(ios_base::fixed, ios_base::floatfield);
KT> oss.precision(2);
KT>
Ага, спасибо, но к сожалению это не подойдет, т.к.:
— очень желательно, чтобы в случае целых числе выводилось
0 1 2 3... (как и происходит в дебаге), а не 0.00, 1.00, 2.00, 3.00...
— y_min может быть числом порядка 0.001 (и y_step соответственно), в этом случае придется ставить precision ~ 5,
а это значит, что целые числа станут выглядеть еще менее привлекательно 1.00000 и т.д.
KT>А причиной может быть оптимизация — попробуй
KT>KT>double volatile y_min = -7.0;
KT>double volatile y_step = 1.4;
KT>...
KT>
Не помогло.
Непонятно почему число 8.88178*10^-16 не округляется до нуля само по себе, хотя с другими числами вроде все в порядке, поэтому я пока ограничился проверкой на ноль: IF |y_min + i*y_step — 0.0| < 0.000001 THEN oss << 0.0.
Кстати, а при помощи sprintf можно добиться чисел типа 1, 2, 3... чтобы не было точек если они не нужны и при этом задавать точность?
Здравствуйте, Аноним, Вы писали:
А>Кстати, а при помощи sprintf можно добиться чисел типа 1, 2, 3... чтобы не было точек если они не нужны и при этом задавать точность?
А как он определит? 3.001 — нужна точка? 3.000001 — нужна? 3.000000000000000000000000000000000000000000000000001? У тебя там есть число 1.4, это 1 2/5. На досуге запиши 1 2/5 двоичной дробью. (У меня вышло 1,011001100110011001100итакдалее — кто хочет проверить?) Дробь бесконечная, потому и возникают погрешности в Nдцатом разряде.
Кстати, для потоков можно устанавливать форматирование чуть покрасивее:
stream << std::fixed << std::setprecision(N) << value; // #.000
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, Аноним, Вы писали:
А>>Кстати, а при помощи sprintf можно добиться чисел типа 1, 2, 3... чтобы не было точек если они не нужны и при этом задавать точность?
да можно. для этого есть формат "%g"
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Здравствуйте, <Аноним>, Вы писали:
А>Есть примерно такой код:
А>А>double y_min = -7.0;
А>double y_step = 1.4;
А>for(int i = 0; i <= 10; ++i)
А>{
А> std::ostringstream oss;
А> oss << (y_min + i*y_step);
А> ...
А>}
А>
А>Проблема в том, что при i == 5, в oss в релизе выводится число 8.88178e-16, хотя в дебаге все нормально — выводится 0. (VS 7.1)
А>В чем дело?
очень странно.. я не смог повторить проблемы
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>