Чи є різниця між цими:
float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);
Як я розумію, обидва випадки мають однаковий результат. Чи є різниця в складеному коді?
#include<cmath>
та використовуйте std::floor
)
bar
?
Чи є різниця між цими:
float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);
Як я розумію, обидва випадки мають однаковий результат. Чи є різниця в складеному коді?
#include<cmath>
та використовуйте std::floor
)
bar
?
Відповіді:
Передача в int скорочуватиметься до нуля. floor()
буде скорочуватися до негативної нескінченності. Це дасть вам різні значення, якщо вони bar
були негативними.
floor()
це є наміром, полягає в тому, якщо значення bar
занадто велике, щоб вмістити його int
.
Як було сказано раніше, для позитивних чисел вони однакові, але вони відмінні для від’ємних чисел. Правило полягає в тому, що 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 і т.д. для нашого застосування. Візьміть його із зерном солі, протестуйте його на вашій системі тощо, але варто розглянути ІМХО.
float
, ні double
- можливо, це double
було вашою заявою. Якщо в C, не забудьте використовувати floorf()
з float
s.
ТАК 101, не змінюйте своє питання після того, як люди відповіли на ваше запитання, замість цього напишіть нове запитання.
Чому, на вашу думку, вони матимуть однаковий результат?
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...
fabs
? Питання було про те floor
. Підлога 0.33333
... є 0
.
EDIT: Оскільки питання, можливо, було змінено через плутанину між fabs()
та floor()
.
Дано оригінальні рядки прикладів запитань:
1. float foo = (int)(bar / 3.0);
2. float foo = fabs(bar / 3.0);
Різниця полягає в тому, що якщо смуга негативна, результат буде негативним з першим, а позитивним - з другим. Перший буде усічений до цілого числа, а другий поверне повне десяткове значення, включаючи дробову частину.
Є дві основні відмінності:
Як зазначали інші, відведення до цілого числа скорочуватиметься до нуля, тоді як floor()
завжди буде скорочуватися до негативної нескінченності; це різна поведінка для негативного операнда.
Ніхто (ще), схоже, не вказав на іншу різницю - якщо ваш аргумент більший або рівний MAX_INT+1
(або менший за -MAX_INT-1
), тоді перенесення до аліменту int
призведе до того, що найбільше бітів буде скинуто (можливо, C) або не визначена поведінка ( C ++ і, можливо, C). EG якщо ваш int
32 біт, у вас буде лише біт знака плюс 31 біт даних. Тож використання цього з double
великим розміром дасть непередбачувані результати.
int
переповнення є те, що аргумент більший або рівний INT_MAX
+1. Симетрично умовою підтоку є те, що аргумент нижчий або дорівнює INT_MIN
-1.
(int) x
- це запит зберегти цілу частину x
(тут немає округлення)
fabs(x)
= | х | так що це >= 0
;
Наприклад: (int) -3.5
повертає -3
; fabs(-3.5)
повертає 3.5
;
Загалом
fabs (x) >= x
для всіх х;
x >= (int) x
якщо x >= 0
x < (int) x
якщо x < 0
floor
, але будьте обережні, що цеdouble
не дляfloat
. C99 також маєfloorf
дляfloat
.