|
Как правильно выполнять округление до ближайшего?, RealView Compiler |
|
|
|
Dec 14 2009, 09:23
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(rezident @ Dec 14 2009, 03:26)  Приведение типа переменной и округление чисел, вообще говоря не очень связанные между собой операции. Самый простой способ общепринятого округления чисел при преобразовании из float в int это прибавление к результату 0.5f непосредственно перед таким преобразованием. Вот, спасибо, теперь буду знать  Хотя и смахивает это на некий костыль... Цитата(aaarrr @ Dec 14 2009, 03:52)  Только числа бывают и отрицательными. ИМХО, лучше вариант (int)floor(x + 0.5) А вот здесь не понял, floor при округлении отрицательного числа (-4.8 + 0.5 = -4.3) даст результат -5?
|
|
|
|
|
Dec 14 2009, 09:44
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(sonycman @ Dec 14 2009, 12:23)  А вот здесь не понял, floor при округлении отрицательного числа (-4.8 + 0.5 = -4.3) даст результат -5? Судя по всему да. ссылкаА я использую вот такие макросы Код #define FROUND(x) ((unsigned long)((x)+0.5f)) #define FROUNDS(x) (((x)>=0)?(long)((x)+0.5f):(long)((x)-0.5f)) До такого не додумался  Цитата(aaarrr @ Dec 14 2009, 02:52)  ИМХО, лучше вариант (int)floor(x + 0.5)
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 14 2009, 09:53
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
demiurg_spbПо идее да - floor округляет до целого, не превышающего начальное значение. Если округлить -4.8 до -4, то -4 будет больше -4.8. Значит, правильно будет -5  В принципе, чтобы юзать floor, надо подключить math.h А чтобы юзать _ffixu_r, которая округлит число безо всяких заморочек, надо подключить rt_fp.h. Не знаю, есть ли между ними какая-то разница  Имхо - самое простое - юзать предложенные вами макросы
|
|
|
|
|
Dec 14 2009, 10:54
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(sonycman @ Dec 14 2009, 12:53)  В принципе, чтобы юзать floor, надо подключить math.h Это не страшно. Цитата А чтобы юзать _ffixu_r, которая округлит число безо всяких заморочек, надо подключить rt_fp.h. А это уже нестандартно (видимо от keil примочки). Цитата Имхо - самое простое - юзать предложенные вами макросы  Это как сказать... У меня два макроса, а ведь можно обойтись одним. Вопрос что оптимальнее. Нужно экспериментировать.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 14 2009, 11:24
|
Частый гость
 
Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561

|
Цитата(sonycman @ Dec 14 2009, 02:19)  Заметил, что при приведении типа с плав. точкой (float) к целочисленному значению, дробная часть просто выкидывается, или производится округление к нулю: было 4.8, стало -> 4. В описании языка C четко сказано, что при приведении типа от вещественного к целочисленному дробная часть просто отсекается.
|
|
|
|
|
Dec 14 2009, 13:16
|
Частый гость
 
Группа: Участник
Сообщений: 92
Регистрация: 23-12-08
Из: Кишинёв
Пользователь №: 42 680

|
sonycman Операция отбрасывания дробной части лёгкая для процессора(наличие fpu роли не играет), в отличии от полноценного округления. Округление нужно далеко не всегда, поэтому можно избежать использования лишних операций. Так наверное во всех вменяемых языках устроено... Цитата(sonycman @ Dec 14 2009, 13:44)  Почему то, в тех редких случаях, когда приходится юзать плавучку, ни разу не приходила в голову мысль портить вычисления использованием столь грубого округления. Ммм.. а например при целочисленном делении ( a / b, a >> x) вам никогда не приходило в голову, что значения напрасно портяться?  (хотя могут быть относительно легко "округлены").
|
|
|
|
|
Dec 14 2009, 16:22
|

Участник

Группа: Участник
Сообщений: 41
Регистрация: 12-10-09
Пользователь №: 52 882

|
предлагаю такой вариант:
long a=5.6; //перед преобразованием умножать на 10, чтоб был остаток от деления в дальнейшем a=a*10; //теперь а=56 a=((int)(a+a%10))/10; //поясню (int) (56+6) и деленое на 10 будет 6, что и необходимо
для отрицательного числа тоже пойдет
ЗЫ при проверке в досовском Borland: задавал а=5.1 далее умножал на 10 и получал а=50.999. кто может объяснить в чем дело?
--------------------
coding, кодинг, koDinГ, copyriting, printing ....
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|