«F» после числа

102

Что означает fпосле цифр? Это от C или Objective-C? Есть ли разница в том, чтобы не добавлять это к постоянному числу?

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

Вы можете объяснить, почему я просто не написал:

CGRect frame = CGRectMake(0, 0, 320, 50);
typeoneerror
источник

Ответы:

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

использует константы типа float. (Константа 0.0 обычно объявляет двойное значение в Objective-C; добавление f в конце - 0.0f - объявляет константу как (32-битное) число с плавающей точкой.)

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

использует целые числа, которые будут автоматически преобразованы в числа с плавающей запятой.

В этом случае между ними нет (практической) разницы.

Фрэнк Шеарар
источник
24
Теоретически компилятор может быть недостаточно умен, чтобы преобразовать их в float во время компиляции, и замедлит выполнение с четырьмя преобразованиями int-> float (которые являются одними из самых медленных преобразований). Хотя в этом случае это почти неважно, всегда лучше указать правильно f, если необходимо: в выражении константа без правильного спецификатора может привести к преобразованию всего выражения в double, а если он находится в жестком цикле, снижение производительности может быть заметно.
Matteo Italia,
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. */
Potatoswatter
источник
26

Он сообщает компьютеру, что это число с плавающей запятой (я предполагаю, что вы здесь говорите о c / c ++). Если после числа нет f, оно считается двойным или целым числом (в зависимости от того, есть ли десятичное число или нет).

3.0f -> float
3.0 -> double
3 -> integer
NickLH
источник
Является ли это соглашение частью стандарта C ++ или оно содержится в компиляторе?
jxramos
1
Насколько я могу судить, это часть стандарта (поправьте меня, если я ошибаюсь). Самый быстрый справочник, который я смог найти, - это open-std.org/jtc1/sc22/open/n2356/lex.html#lex.fcon , но, вероятно, есть более свежие ссылки, если вы захотите их найти.
NickLH
5

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

Вероятность появления ошибки не так уж и мала. Многие программы отказались от непродуманного сравнения с плавающей запятой или предположили, что 0,1 точно представимо.

Ганс Пассан
источник
4

То, fо чем вы говорите, вероятно, предназначено для того, чтобы сообщить компилятору, что он работает с float. Когда вы опускаете f, он обычно переводится как двойной.

Оба являются числами с плавающей запятой, но floatиспользует меньше битов (следовательно, меньше и менее точен), чем a double.

Юрий
источник
3

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

Вы можете использовать целые числа для указания значений здесь, и в этом случае это не будет иметь никакого значения, но использование правильного типа - хорошая привычка - согласованность - это вообще хорошо, и если вам нужно изменить эти значения позже, вы С первого взгляда узнаю, что это за тип.

Пол Р
источник
2

От C. Это означает буквальную константу типа float. Вы можете опустить как «f», так и «.0» и использовать целые числа в своем примере из-за неявного преобразования целых чисел в числа с плавающей запятой.

Дикая кошка
источник
1

Это почти наверняка из C и отражает желание использовать тип float, а не двойной. Это похоже на суффиксы, такие как L в числах, чтобы указать, что они являются длинными целыми числами. Вы можете просто использовать целые числа, и компилятор выполнит автоматическое преобразование по мере необходимости (для этого конкретного сценария).

тиранид
источник
0

Обычно он сообщает компилятору, что значение является floatцелым числом с плавающей запятой. Это означает, что он может хранить целые числа, десятичные значения и экспоненты, например 1, 0.4или 1.2e+22.

Полиномиальный
источник