“F” після номера


102

Що робить f цифри після цифр? Це від C або Objective-C? Чи є різниця в тому, щоб не додавати це до постійної кількості?

CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);

Чи можете ви пояснити, чому я не просто писав би:

CGRect frame = CGRectMake(0, 0, 320, 50);

Відповіді:


88
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);

використовує поплавкові константи. (Константа 0,0 зазвичай оголошує дубль в Objective-C; ставлячи f в кінці - 0,0f - оголошує константу як (32-бітний) поплавок.)

CGRect frame = CGRectMake(0, 0, 320, 50);

використовує ints, які будуть автоматично перетворені в плавці.

У цьому випадку між ними немає (практичної) різниці.


24
Теоретично компілятор може бути недостатньо розумним, щоб перетворити їх у плаваючу під час компіляції, і сповільнить виконання за допомогою чотирьох конверсій int> float (які є одними з найповільніших каст). Хоча в цьому випадку це майже неважливо, завжди краще вказати правильно f, якщо це потрібно: у виразі константа без правильного специфікатора може змусити перетворити весь вираз у подвійний, і якщо він знаходиться у тісному циклі, показник може бути хітом помітний.
Маттео Італія

60

Якщо ви сумніваєтесь, перевірте вихід асемблера. Наприклад, напишіть невеликий, мінімальний фрагмент, наприклад, як це

#import <Cocoa/Cocoa.h>

void test() {
  CGRect r = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);
  NSLog(@"%f", r.size.width);
}

Потім складіть його до асемблера з -Sопцією.

gcc -S test.m

Збережіть висновок асемблера у test.sфайлі та видаліть .0fіз констант та повторіть команду компіляції. Потім зробіть diffнове test.sта попереднє. Подумайте, що має показати, чи є реальні відмінності. Я думаю, що занадто багато людей мають бачення того, що вони вважають компілятором, але наприкінці дня слід знати, як перевірити будь-які теорії.


11
Вихід виявився для мене однаковим, навіть без жодного -O. Я на i686-apple-darwin10-gcc-4.2.1 (GCC)
kizzx2

2
Я спробував наведений вище приклад з LLVM версії 7.0.0 (clang-700.0.65) x86_64-apple-darwin15.0.0 і файли .out також були однаковими.
Нік

43

Іноді є різниця.

float f = 0.3; /* OK, throw away bits to convert 0.3 from double to float */
assert ( f == 0.3 ); /* not OK, f is converted from float to double
   and the value of 0.3 depends on how many bits you use to represent it. */
assert ( f == 0.3f ); /* OK, comparing two floats, although == is finicky. */

26

Це повідомляє комп’ютеру, що це номер з плаваючою комою (я припускаю, що ви тут говорите про c / c ++). Якщо після числа немає f, воно вважається подвійним або цілим числом (залежно від того, є десятковий чи ні).

3.0f -> float
3.0 -> double
3 -> integer

це умовна частина стандарту C ++ чи вона міститься в компіляторі?
jxramos

1
Наскільки я можу сказати, це частина стандарту (хтось мене виправить, якщо я помиляюся). Найшвидший посилання, який я міг би знайти, є open-std.org/jtc1/sc22/open/n2356/lex.html#lex.fcon , але, мабуть, є більш актуальні посилання, якщо ви хочете їх шукати.
NickLH

5

Літерал з плаваючою комою у вихідному коді аналізується як подвійний. Присвоївши його змінній, що має тип float, втратить точність. Багато точності, ви викидаєте 7 значущих цифр. Постфікс "f" дозволить вам сказати компілятору: "Я знаю, що я роблю, це навмисно. Не переймайте мене про це".

Шанси на виробництво помилки не такі малі до речі. Багато програм охоплюють непродумане порівняння з плаваючою точкою або припускаючи, що 0,1 є точно представним.


4

Те, про fщо ви говорите, ймовірно, має на меті сказати компілятору, що він працює з поплавком. Коли ви опускаєте f, це, як правило, перекладається в подвійний.

Обидва - це числа з плаваючою комою, але floatвживається менше біт (таким чином, менший і менш точний), ніж a double.


3

Це річ C - літерали з плаваючою комою за замовчуванням мають подвійну точність (подвійну). Додавання суфікса f робить їх однозначною точністю (float).

Ви можете використовувати ints для вказівки значень тут, і в цьому випадку це не має ніякого значення, але використовувати правильний тип - це добра звичка потрапляти - послідовність - це взагалі гарна річ, і якщо вам потрібно змінити ці значення пізніше, ви Я з першого погляду дізнаюся, що вони типу.


2

Від C. Це означає поплавкова буквальна константа. Ви можете опустити як "f", так і ".0" і використовувати ints у своєму прикладі через неявне перетворення ints у floats.


1

Це майже напевно від С і відображає бажання використовувати тип "поплавок", а не "подвійний" тип. Він схожий із суфіксами, такими як L на числах, що означає, що вони є довгими цілими числами. Ви можете просто використовувати цілі числа, і компілятор автоматично перетворить у відповідних випадках (для цього конкретного сценарію).


0

Зазвичай повідомляє компілятору, що значення є a float, тобто число з плаваючою точкою. Це означає, що він може зберігати цілі числа, десяткові значення та експоненти, наприклад 1, 0.4або 1.2e+22.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.