1

Тема: ceil з мінусовими числами

Чи є якась функція, що повертає

-1.5 -> -2
 1.5 ->  2

бо поки що я роблю так:

int ceil_abs(float f)
{
    return f < 0 ? floor(f) : ceil(f);
}

2 Востаннє редагувалося ReAl (01.08.2016 16:05:49)

Re: ceil з мінусовими числами

Та ніяк, лише йогою займатися.
Можна такою. :-)

#include <iostream>
#include <cmath>

using namespace std;

int ceil_abs(float f)
{
        return copysignf(ceilf(fabsf(f)),f);
}

#define TST(a)  cout << #a << " -> " << ceil_abs(a) << endl

int main()
{
        TST(1.5);
        TST(-1.5);
}

змінено: додав суфікси f до функцій — якщо вже аргумент float, щоб не симкало туди-сюди у double

Подякували: Yola1

3 Востаннє редагувалося VTrim (01.08.2016 16:34:48)

Re: ceil з мінусовими числами

У PHP робив так, там така ж проблема.
В С буде приблизно те ж..

$f = -1.5; //вхідне число
$result = ceil(abs($f)) * -1; //заокруглюємо вже додатнє число, а результат робимо від'ємним.
echo $result; //-2

4

Re: ceil з мінусовими числами

Спробував глянути на тему під кутом швидкості роботи.
Варіант return f < 0 ? floor(f) : ceil(f); має явну перевірку з умовним переходом, який у загальному випадку непередбачуваний.
А другий варіант на перший погляд лінійний, fabsf взагалі одна команда процесора.
Та з'ясувалося, що, принаймні для gcc, ота copysignf не копіює знаковий біт з однієї змінної в іншу, а робить, у С-шному еквіваленті, щось таке

float copysignf(float dst, float src)
{
        dst = fabsf(dst);       // це одна команда
        if (signbit(src)) {     // тут саме зі слова src бітовою маскою виймається знак
                dst = -dst;     // це теж одна команда
        }
        return dst;
}

Тобто умовний перехід все одно є, виймання знаку та перевірка з переходом на око приблизно еквівалентні f < 0 ?, тобто різниця невелика і може бути в будь-який бук.