Подтвердить что ты не робот

Каково значение 0.0f при инициализации (в C)?

Я видел код, в котором люди инициализируют float-переменные следующим образом:

float num = 0.0f;

Есть ли существенная разница между этим и только следующим ниже?

float num = 0; 

Спасибо..:)

4b9b3361

Ответ 1

float x = 0 имеет неявный typecast от int до float.
float x = 0.0f не имеет такого типа. float x = 0.0 имеет неявный typecast от double to float.

В зависимости от компилятора неявный typecast может потребовать от компилятора генерации дополнительного кода.

Ответ 2

Просто считается, что хорошая практика инициализирует переменную с константой литерала того же типа. В этом случае у вас есть переменная float, и вы должны инициализировать ее константой с плавающей буквой, т.е. 0.0f, а не int (0), которая затем неявно приводится к float.

Ответ 3

Вероятно, причина в том, что они когда-то писали что-то вроде:

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 следует учитывать как стоимость разработчика для выполнения этой оптимизации.

Ответ 4

Ну, строго говоря, 0 - целое число, поэтому float num = 0 требует кастинга из целого числа для float. Но я предполагаю, что компилятор сделает это для вас в любом случае. Я предполагаю, что люди используют 0.0f, чтобы подчеркнуть, что это float, поэтому никто не ошибается в нем для целого числа.

Ответ 5

Пол Р написал ответ. Второй пример имеет целочисленное значение инициализации.

Вы всегда должны использовать инициализатор того же типа, что и инициализируемая переменная. Это позволяет избежать любого преобразования во время компиляции (в идеале) или времени выполнения (ленивые компиляторы: все эти ленивые?). И, возможно, что более важно, преобразование может привести к каким-то странным вещам в общем случае.

Здесь преобразование должно делать именно то, что ожидается, но оно по-прежнему является хорошим стилем и позволяет избежать предупреждения о компиляторе.

Ответ 6

Я не вижу причин использовать это для процесса инициализации. Но для операций с литералами с плавающей запятой это было бы полезно. Например:

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;