Есть ли разница между ними:
float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);
Как я понимаю, оба случая имеют одинаковый результат. Есть ли разница в скомпилированном коде?
Есть ли разница между ними:
float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);
Как я понимаю, оба случая имеют одинаковый результат. Есть ли разница в скомпилированном коде?
Литье в int будет усекаться к нулю. floor()
будет усекать в сторону отрицательного бесконечного. Это даст вам разные значения, если bar
были отрицательными.
Как уже было сказано, для положительных чисел они одинаковы, но они отличаются для отрицательных чисел. Правило в том, что int округляется к 0, а пол округляется к отрицательной бесконечности.
floor(4.5) = (int)4.5 = 4
floor(-4.5) = -5
(int)(-4.5) = -4
Говоря об этом, также существует разница во времени выполнения. В моей системе я приурочил, что кастинг по крайней мере в 3 раза быстрее, чем пол.
У меня есть код, который нуждается в работе на полу с ограниченным диапазоном значений, включая отрицательные числа. И он должен быть очень эффективным, поэтому мы используем для него следующую функцию:
int int_floor(double x)
{
return (int)(x+100000) - 100000;
}
Конечно, это не удастся для очень больших значений x (вы столкнетесь с некоторыми проблемами переполнения) и для отрицательных значений ниже -100000 и т.д. Но я сделал так, чтобы он был как минимум в 3 раза быстрее, чем пол, что было очень важно для нашего приложения. Возьмите его с солью, проверьте ее на своей системе и т.д., Но стоит подумать об ИМХО.
Почему вы думаете, что у них будет тот же результат?
float foo = (int)(bar / 3.0) //will create an integer then assign it to a float
float foo = fabs(bar / 3.0 ) //will do the absolute value of a float division
bar = 1.0
foo1 = 0;
foo2 = 0.33333...
EDIT: поскольку вопрос может быть изменен из-за путаницы между fabs()
и floor()
.
Учитывая исходные строки примера вопроса:
1. float foo = (int)(bar / 3.0);
2. float foo = fabs(bar / 3.0);
Разница в том, что если бар отрицательный, результат будет отрицательным с первым, но положительным со вторым. Первый будет усечен до целого числа, а второй вернет полное десятичное значение, включая дробную часть.
Да. fabs
возвращает абсолютное значение своего аргумента, а приведение в int вызывает усечение деления (вплоть до ближайшего int), поэтому результаты почти всегда будут разными.
Существуют два основных отличия:
Как указывали другие, приведение к целому числу будет усекаться к нулю, тогда как floor()
всегда будет усекать в сторону отрицательной бесконечности; это другое поведение для отрицательного операнда.
Никто (пока) не указал еще одно отличие - если ваш аргумент больше или равен MAX_INT+1
(или меньше, чем -MAX_INT-1
), то приведение к int
приведет к (C, возможно) или undefined поведение (С++ и, возможно, C). EG, если ваш int
- 32 бита, у вас будет только бит знака плюс 31 бит данных. Поэтому использование этого с большим размером double
приведет к непредвиденным результатам.
(int) x
- это запрос на сохранение целой части x
(здесь нет округления)
fabs(x)
= | x | так что >= 0
;
Пример: (int) -3.5
возвращает -3
; fabs(-3.5)
возвращает 3.5
;
В целом,
fabs (x) >= x
для всех x;
x >= (int) x
, если x >= 0
x < (int) x
, если x < 0