Russian Qt Forum

Программирование => С/C++ => Тема начата: Eten от Февраль 24, 2011, 06:51



Название: Как сделать отсечение дробной части?
Отправлено: Eten от Февраль 24, 2011, 06:51
Облазил и перечитал уйму информации, но везде говорится только об округления дробных чисел до целых. А как можно сделать отсечение дробной части, чтобы не округлять число?

Да и есть ли вообще простой алгоритм отделения дробной и целой части у числа, как это например можно было спокойно сделать на Object Pascale?

З.Ы.
Помню, что это как-то возможно сделать не прибегая к строкам, но уже давно все забыл и не могу вспомнить.


Название: Re: Как сделать отсечение дробной части?
Отправлено: Fat-Zer от Февраль 24, 2011, 08:09
эмм... вообще приведение к int как раз отбрасывает дробную часть
Код
C++ (Qt)
double x=123.56;
int y=x; // y= 123
 


Название: Re: Как сделать отсечение дробной части?
Отправлено: Akon от Февраль 24, 2011, 08:33
Функции библиотеки С, типа floor(), ceil().


Название: Re: Как сделать отсечение дробной части?
Отправлено: Eten от Февраль 24, 2011, 08:44
Функции библиотеки С, типа floor(), ceil().
Это понятно, но как быть с числом, если его значение превышает (например float размерность больше, чем у int и long int)? Ведь в таком случае я превышаю границы целых чисел и там будет котовасия, а не записывание максимального значения границы целого типа (в этом можно убедиться использовав pow).

Кстати, а могу ли я написать тип так: long long long int? И в чем ограничения такого типа?


Название: Re: Как сделать отсечение дробной части?
Отправлено: Fat-Zer от Февраль 24, 2011, 08:54
Кстати, а могу ли я написать тип так: long long long int? И в чем ограничения такого типа?
нет только long long. Ограничения зависят от платформы, гарантируется только:
sizeof(char)<=sizeof(short)<=sizeof(int)<=sizeof(long)<=sizeof(long long)

ceil() и floor() как раз возвращает флоат-типы. не понимаю в чём проблемма...


Название: Re: Как сделать отсечение дробной части?
Отправлено: Eten от Февраль 24, 2011, 09:09
Блин, сам еще молодой, а спрашиваю, как седая башка. Все как всегда очень просто!

Выделение целой части или отсечение дробной части числа можно сделать с помощью floor, т.к. она не увеличивает число при округлении до целого.

Выделение дробной части: число - floor(число).

Округление до целого числа в зависимости от цифры после запятой:
Код:
double d = 40.6;
if (d > floor(d)+0.5) d = ceil(d); else d = floor(d);


Название: Re: Как сделать отсечение дробной части?
Отправлено: Eten от Февраль 24, 2011, 09:15
ceil() и floor() как раз возвращает флоат-типы. не понимаю в чём проблемма...
Как раз таки нет там float-а, там стоит double, как в качестве возвращаемого значения, так и в качестве параметра. И так почти во всех математических функциях с вещевственными числами, float вместо double в них я ни разу не видел.  ;)

Хотя проблема бывает, когда переводишь в целые из дробных. Если границу превышает, получается отсебятина. Т.е. при превышении положительной границы long типом флоат, в переменной типа long можно получить максимальную отрицательную границу, а не как надо (т.е. положительную). Либо может записаться число не превышающая границу целого типа переменной. У меня вот и бывало.  ::)


Название: Re: Как сделать отсечение дробной части?
Отправлено: Igors от Февраль 24, 2011, 11:07
Блин, сам еще молодой, а спрашиваю, как седая башка. Все как всегда очень просто!

Выделение целой части или отсечение дробной части числа можно сделать с помощью floor, т.к. она не увеличивает число при округлении до целого.

Выделение дробной части: число - floor(число).

Округление до целого числа в зависимости от цифры после запятой:
Код:
double d = 40.6;
if (d > floor(d)+0.5) d = ceil(d); else d = floor(d);
Это "не очень просто"  :)
Проверьте на отрицательных d


Название: Re: Как сделать отсечение дробной части?
Отправлено: Eten от Февраль 24, 2011, 12:11
М-да, ясненько. Вот эта функция уж точно будет работать как надо:

Код:
double round(double Number)
{
    bool Negative = Number < 0 ? true: false;
    Number = fabs(Number);

    if (Number > floor(Number)+0.5)
        Number = ceil(Number);
    else
        Number = floor(Number);

    return Negative ? Number * (-1) : Number;
}

Как говорится, все остальное мы исправим зонтом.  ;D

З.Ы.
Надо только вспомнить насчет округления отрицательных чисел. Чтобы точно быть уверенным в функции.

З.З.Ы.
Да все правильно работает, -4.6 округляется до -5, а 4.6 до 5.


Название: Re: Как сделать отсечение дробной части?
Отправлено: brankovic от Февраль 24, 2011, 12:31
а так почему нельзя?

Код
C++ (Qt)
double round (double d)
{
  return floor (d + 0.5);
}
 


Название: Re: Как сделать отсечение дробной части?
Отправлено: Пантер от Февраль 24, 2011, 12:46
А если d отрицательное?


Название: Re: Как сделать отсечение дробной части?
Отправлено: Eten от Февраль 24, 2011, 12:49
а так почему нельзя?

Код
C++ (Qt)
double round (double d)
{
  return floor (d + 0.5);
}
 

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

З.Ы.
Оох, приходится вспоминать такие мелочи на Си++ при работе с Qt4. Вроде бы и всем ясно, но это же информация по умолчанию. Кто-то знает, а кто-то нет.  ::)

З.З.Ы.
Вариант, brankovic работает также, только он короче. А мой вариант может сгодится тем, у кого есть сомнения в таких вопросах и желание все проверить самим.  ;)


Название: Re: Как сделать отсечение дробной части?
Отправлено: Eten от Февраль 24, 2011, 13:08
Вот кстати, дополнение к сказанному. Первая функция выдает дробную часть любого числа, а вторая целую часть любого числа.  ;)

Код:
double fractional(double Number)
{
    return Number < 0 ? Number - ceil(Number) : Number - floor(Number);
}

double integer(double Number)
{
    return Number < 0 ? ceil(Number) : floor(Number);
}


Название: Re: Как сделать отсечение дробной части?
Отправлено: Igors от Февраль 24, 2011, 14:31
Вот кстати, дополнение к сказанному. Первая функция выдает дробную часть любого числа, а вторая целую часть любого числа.  ;)
Для этого есть ф-ция modf


Название: Re: Как сделать отсечение дробной части?
Отправлено: Eten от Февраль 25, 2011, 07:20
Вот кстати, дополнение к сказанному. Первая функция выдает дробную часть любого числа, а вторая целую часть любого числа.  ;)
Для этого есть ф-ция modf

Вот, что нашел по этой функции(взято здесь (http://www.studfiles.ru/dir/cat32/subj1261/file11713/view104953/page21.html)):
Цитировать
Назначение        Разделяет целую и дробную части

Синтаксис         #include<math.h>
                  double modf(double x,double *ipart);

Прототип в        math.h

Замечания         modf  разбивает  значение  переменной  х   типа
                  double  на  две  части:  целую и дробную. Целая
                  часть запоминается в  ipart,  а  дробная  часть
                  возвращается.

Возвращаемое      modf возвращает дробную часть х
значение

В общем, тут дело потребностей. Т.к. написать так, будет не правильно:
Код:
    double d2=4.6;
    d2=modf(d2,NULL);

Там видно стоит поверка на пустую ссылку. А было б удобнее брать только, или дробная часть, или целую, чем занимать еще переменную (времена уже не те, да и памяти больше).  ;)


Название: Re: Как сделать отсечение дробной части?
Отправлено: Fat-Zer от Февраль 25, 2011, 08:47
ceil() и floor() как раз возвращает флоат-типы. не понимаю в чём проблемма...
Как раз таки нет там float-а, там стоит double, как в качестве возвращаемого значения, так и в качестве параметра. И так почти во всех математических функциях с вещевственными числами, float вместо double в них я ни разу не видел.  ;)
флоат-типы - подразумевал float, double, long double
Cишная - да принимает только double, однако в C++, как и многие други, она (std::floor()) перегружена для всех этих типов.  ;)