Где Round () в C ++?

Дубликат: round () для float в C ++


Я использую VS2008 и включил math.h, но все еще не могу найти круглую функцию. Он существует?

Я вижу кучу добавлений 0.5 и преобразований в решения в Google. Это лучшая практика?


person Jason Punyon    schedule 16.02.2009    source источник
comment
добавить 0,5 и преобразовать в int не будет работать для отрицательных чисел. Приведение усекается (округляется от -4,5 до -4). Таким образом, попытка округления -5.0 даст вам результат -4 с помощью этого метода. Замените гипс на ceil (), и он должен работать. Но да, вы должны реализовать свой собственный или найти его в сторонней библиотеке.   -  person jalf    schedule 16.02.2009
comment
Э, конечно, предположим, что я написал floor () выше. Чтобы использовать ceil, вам нужно вычесть 0,5   -  person jalf    schedule 16.02.2009
comment
@jalf, как я уже отмечал в моем ответе на дубли, есть много проблем с прокруткой вашего собственного, и сегодня, даже если вы застряли на бусте C ++ 03, было бы лучше, чем пытаться откатить свой собственный.   -  person Shafik Yaghmour    schedule 14.07.2014


Ответы (4)


Вы можете использовать std::round() из C ++ 11.

Если вы по-прежнему придерживаетесь старых стандартов, вы можете использовать std::floor(), который всегда округляется до меньшего числа, а std::ceil() всегда округляется до большее число.

Чтобы получить нормальное поведение округления, вы действительно должны использовать floor(i + 0.5).

В этом случае возникнут проблемы с отрицательными числами, решение этой проблемы - использование ceil () для отрицательных чисел:

double round(double number)
{
    return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5);
}

Другой, более чистый, но более ресурсоемкий способ - использовать строковый поток и манипуляторы ввода / вывода:

#include <iostream>
#include <sstream>

double round(double val, int precision)
{
    std::stringstream s;
    s << std::setprecision(precision) << std::setiosflags(std::ios_base::fixed) << val;
    s >> val;
    return val;
}

Используйте второй подход только в том случае, если у вас достаточно ресурсов и / или вам необходимо контролировать точность.

person Patrick Glandien    schedule 16.02.2009
comment
Вы думаете, что чище преобразовать в строку и обратно? - person Paul Tomblin; 16.02.2009
comment
Да, используя метод + 0,5, вы столкнетесь с проблемами с отрицательными числами, а также не сможете контролировать точность. - person Patrick Glandien; 16.02.2009
comment
+0,5 должно работать нормально, пока вы используете floor (). Во всяком случае, тогда это становится вопросом правильности, а не того, что чище. - person jalf; 16.02.2009
comment
какие проблемы с отрицательными числами? если вам не нужна точность управления, тогда решение для строкового потока работает медленнее без причины. возможно, здесь будет иметь смысл специализация шаблона, если вы действительно хотите обеспечить контроль точности. - person wilhelmtell; 16.02.2009
comment
Кроме того, я должен напомнить вам, что 0,5 представлено как точное число. - person wilhelmtell; 16.02.2009
comment
Также необходимо включить ‹iomanip› (с использованием MSVC 2012), чтобы использовать функцию округления. - person Vertexwahn; 07.05.2013
comment
Я предпочитаю copysignf(floorf(fabs(x) + 0.5f), x), поскольку он не имеет веток, а код, имитирующий ветку, буквально является bin-ops (abs - ›&~0x80000000, copysign - это битовая передача и т. Д.) - person LiraNuna; 24.03.2014
comment
См. Мой ответ здесь, также доступны trunc и boost. Также см. Мою ссылку на статьи Паскаля Куока о том, почему создание собственного может быть очень сложным. - person Shafik Yaghmour; 27.06.2014
comment
@wilhelmtell какие проблемы с отрицательными числами? - ›в крайнем случае round(-0.0) этот ответ возвращает 0.0. -0.0 можно ожидать. - person chux - Reinstate Monica; 03.08.2015
comment
Вопрос начинается с того, что я использую VS2008 ... и ответ начинается с того, что вы можете использовать C ++ 11 ... Вам не кажется, что здесь есть какое-то противоречие? В VC2008 нет функции std :: round (). - person il--ya; 12.04.2018
comment
Обратите внимание, что трюк +0,5 не совсем верен: blog .frama-c.com / index.php? post / 2013/05/02 / nearintf1 - person ChriS; 23.05.2018

Использование floor(num + 0.5) не сработает для отрицательных чисел. В этом случае вам нужно использовать ceil(num - 0.5).

double roundToNearest(double num) {
    return (num > 0.0) ? floor(num + 0.5) : ceil(num - 0.5);
}
person Bill the Lizard    schedule 16.02.2009

На самом деле в Microsoft math.h нет круглой функции.
Однако вместо этого вы можете использовать статический метод Math :: Round ().
(В зависимости от типа вашего проекта.)

person Sani Singh Huttunen    schedule 16.02.2009
comment
Visual Studio теперь поддерживает круглый см. Мой комментарий здесь также см. Мой answer для того, что я считаю полным набором альтернатив в случае, когда вы не можете использовать более современный компилятор. - person Shafik Yaghmour; 01.07.2014

Я не знаю, лучшая это практика или нет, но использование метода 0,5 с полом () кажется правильным решением.

person Elroy    schedule 16.02.2009