round in C++
От: vadimcher  
Дата: 29.08.09 17:30
Оценка:
В связи с одним обсуждением в Этюдах мне стало интересно, какой вариант round() народ использует на практике (в math.h есть ceil и floor, но если требуется именно round()). Я сам обычно использую "округление вверх для .5": (int)((double)x + 0.5)). В стандарте C99 round() делает более грамотное округление -- половинчатые числа округляются от нуля, т.е. 0.5->1, -0.5->-1.

Оказалось, что это не такая уж и простая задача. Вот, наткнулся на ветку, в которой народ обсуждает, как это грамотно сделать: http://codingforums.com/showthread.php?t=10827. Особенно понравился последний комментарий, после которого ветку закрыли...

When my browser first loaded this page and I read your post, I really didn't care a whole lot as I was but immediately convinced that you were quite ordinary in terms of intelligence, but when I found out that jkd had posted his message before you had posted yours, I began to realize the maginute of your lack of at birth given gifts. Your post was so unnecessary and stupid that it made me euforic about my IQ-result of 144, which a few days ago I thought to be shamefully low compared to certain idols of mine.

I am but certain that I have written nothing of what you want to hear, but the truth has mysterious ways of deploying itself. Though it could this time be explained by my adrenaline aneurism or my autistic behaviour, I think you should gather all your mental and physical resources and repeatedly attempt to increase thy brain acitivity.


А вот зайца кому, зайца-выбегайца?!
Re: round in C++
От: Meer  
Дата: 29.08.09 19:04
Оценка: 1 (1)
Здравствуйте, vadimcher, Вы писали:

V>В связи с одним обсуждением в Этюдах мне стало интересно, какой вариант round() народ использует на практике


Функции округления из boost.
Re[2]: round in C++
От: vadimcher  
Дата: 29.08.09 19:07
Оценка:
Здравствуйте, Meer, Вы писали:

M>Здравствуйте, vadimcher, Вы писали:


V>>В связи с одним обсуждением в Этюдах мне стало интересно, какой вариант round() народ использует на практике


M>Функции округления из boost.


Ну boost -- это буст, но ради округления буст ставить, если нет. В c99 вроде бы есть round(). Кроме того, как выяснилось, даже такой вопрос иногда вызывает трудности.

А вот зайца кому, зайца-выбегайца?!
Re: round in C++
От: shks57  
Дата: 29.08.09 19:47
Оценка:
Здравствуйте, vadimcher, Вы писали:

V>В связи с одним обсуждением в Этюдах мне стало интересно, какой вариант round() народ использует на практике (в math.h есть ceil и floor, но если требуется именно round()). Я сам обычно использую "округление вверх для .5": (int)((double)x + 0.5)). В стандарте C99 round() делает более грамотное округление -- половинчатые числа округляются от нуля, т.е. 0.5->1, -0.5->-1.


Мне пришлось написать свою функцию. Она округляет модуль числа до ближайшего целого, а потом добавляет знак.
//--- Округляет число до ближайшего целого ---
int rint(double fff)
{
int sign,res;
double vsp,ost;

vsp = fff / fabs(fff);
if(vsp < 0)
sign = -1;
else
sign = 1;

vsp = fff * sign; //Модуль f
ost = fmod(vsp,1);
if(ost < 0.5)
res = int(vsp);
else
res = int(vsp + 1.0);

return res*sign;
}
Re: round in C++
От: dad  
Дата: 29.08.09 19:55
Оценка:
такого монстрика вот нашел (даже не помню что делает, вроде окргление до нужного знака):

    template<typename typeT>
    struct abs{
        typeT operator()(typeT a){
            return (a < 0 ? -a : a);
        }
    };    


    template<typename typeT>
    struct isequal{
        bool operator()(typeT a, typeT b) const{
            if (std::numeric_limits<typeT>::is_integer) return a == b;
            abs<typeT> ab;            
            return !(  ab( a - b )  >     
                ( std::numeric_limits<typeT>::epsilon() * 
                    (  ab( a ) + ab( b ) )    )      );    
        }
    };


    template<typename typeT, int sharpT = -1>
    struct round 
    {
        typeT operator () (typeT src) const
        {
            if (sharpT == 0 || isequal<typeT>()(src,0)) return src;
            typeT rez = 0;
            if (sharpT < 0)
                rez = static_cast<typeT>( 
                    std::floor(src / (-sharpT)   + 0.5) * (-sharpT)) ;
            else 
                rez = static_cast<typeT>( 
                    std::floor(src * sharpT  + 0.5) / typeT(sharpT));
            return  rez;
        } 
    };
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Re: round in C++
От: K13 http://akvis.com
Дата: 31.08.09 06:23
Оценка: :)
V>В связи с одним обсуждением в Этюдах мне стало интересно, какой вариант round() народ использует на практике (в math.h есть ceil и floor, но если требуется именно round()). Я сам обычно использую "округление вверх для .5": (int)((double)x + 0.5)). В стандарте C99 round() делает более грамотное округление -- половинчатые числа округляются от нуля, т.е. 0.5->1, -0.5->-1.

((double)x + 0.5). Но приведение к инту -- математическое ( 0.4f -> 0, -0.4f -> -1 ), через floor().

Иначе возникают нюансы при работе алгоритмов, разработанных математиками.
Re: round in C++
От: saf_e  
Дата: 31.08.09 12:54
Оценка:
Обычно в каждом новом проекте добавляю такую ф-цию:

template<typename _Int>
_Int round(double val)
{
return (_Int)(val < 0 ? val — .5 : val + .5);
}

Template -- чтобы избежать ненужных приведений...
Re[2]: round in C++
От: blackhearted Украина  
Дата: 31.08.09 14:12
Оценка:
Здравствуйте, K13, Вы писали:



K13>((double)x + 0.5). Но приведение к инту -- математическое ( 0.4f -> 0, -0.4f -> -1 ), через floor().


K13>Иначе возникают нюансы при работе алгоритмов, разработанных математиками.


Вроде так же и в бусте сделано.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.