Есть ли разница между ними:
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