Я видел код, в котором люди инициализируют float-переменные следующим образом:
float num = 0.0f;
Есть ли существенная разница между этим и только следующим ниже?
float num = 0;
Спасибо..:)
Я видел код, в котором люди инициализируют float-переменные следующим образом:
float num = 0.0f;
Есть ли существенная разница между этим и только следующим ниже?
float num = 0;
Спасибо..:)
float x = 0 имеет неявный typecast от int до float.
float x = 0.0f не имеет такого типа.
float x = 0.0 имеет неявный typecast от double to float.
В зависимости от компилятора неявный typecast может потребовать от компилятора генерации дополнительного кода.
Просто считается, что хорошая практика инициализирует переменную с константой литерала того же типа. В этом случае у вас есть переменная float, и вы должны инициализировать ее константой с плавающей буквой, т.е. 0.0f
, а не int (0
), которая затем неявно приводится к float.
Вероятно, причина в том, что они когда-то писали что-то вроде:
float f = 1 / i; // i an integer
Отлаживая это, они поклялись всегда украшать литералы достаточно, чтобы получить правильный тип:
float f = 1.0f / i;
В этом случае .0
должен обеспечить, чтобы деление было плавающей точкой, а не целочисленным делением. f
заключается в том, что нет необходимости в выполнении операции в double
- я ожидаю, что там будет больше шансов на реализацию, где 1.0/i
будет значительно медленнее без выгоды (эмуляция программного обеспечения с плавающей точкой, безразличная оптимизация), чем один, где 1.0f
значительно медленнее, не приносит никакой пользы (если double быстрее, чем float, потому что у вас есть аппаратное обеспечение fp, поэтому преобразование между ними будет очень быстрым, поэтому не произойдет значительного замедления).
У вас есть привычка украшать литералы, вы можете написать:
float f = 0.0f;
хотя он имеет точно такой же эффект, как float f = 0.0;
или float f = 0;
.
Конечно, автор, возможно, лично не прошел это откровение, они могли бы просто унаследовать стиль другого, кто это сделал.
Я просто напишу 0
.
R.. указывает в комментарии другой ответ, что письмо 0 также имеет то преимущество, что при изменении типа f
в будущем вам не нужно обновлять литерал, чтобы он соответствовал. И если задание отделено от определения, а затем измените:
float f = something
// some time later
f = 0.1f;
в
double f = something;
// some time later
f = 0.1f;
вероятно, ошибка. Лучше использовать 0.1
и позволить компилятору усекать, если необходимо. Вероятно, вы могли бы утверждать, что использование float
вообще - это оптимизация, для пространства, если не для времени, а бремя борьбы с любыми различиями между float и double следует учитывать как стоимость разработчика для выполнения этой оптимизации.
Ну, строго говоря, 0 - целое число, поэтому float num = 0
требует кастинга из целого числа для float. Но я предполагаю, что компилятор сделает это для вас в любом случае. Я предполагаю, что люди используют 0.0f
, чтобы подчеркнуть, что это float, поэтому никто не ошибается в нем для целого числа.
Пол Р написал ответ. Второй пример имеет целочисленное значение инициализации.
Вы всегда должны использовать инициализатор того же типа, что и инициализируемая переменная. Это позволяет избежать любого преобразования во время компиляции (в идеале) или времени выполнения (ленивые компиляторы: все эти ленивые?). И, возможно, что более важно, преобразование может привести к каким-то странным вещам в общем случае.
Здесь преобразование должно делать именно то, что ожидается, но оно по-прежнему является хорошим стилем и позволяет избежать предупреждения о компиляторе.
Я не вижу причин использовать это для процесса инициализации. Но для операций с литералами с плавающей запятой это было бы полезно. Например:
float a=0.43, b;
b = 0.5*a + 2.56*a*a;
Литералы с плавающей точкой без суффикса считаются двойными. Таким образом, для этого вычисления "a" будет дублироваться по типу, и окончательный ответ RHS-оценки будет двойной. Во время присвоения двойное значение RHS отбрасывается в float и присваивается "b". Это ухудшит производительность, если машина не имеет FPU с двойной точностью. Чтобы избежать этого и использовать float для полного вычисления. используются суффиксы. Например,
float a=0.43, b;
b = 0.5f*a + 2.56f*a*a;