Я часто использую неправильные литералы в выражениях, например деление поплавка на int, например:
float f = read_f();
float g = f / 2;
Я считаю, что компилятор в этом случае сначала преобразует литерал int (2) в float, а затем применяет оператор деления. GCC и Clang всегда пропускают подобные вещи, но Visual C ++ предупреждает о неявном преобразовании. Поэтому я должен написать это так:
float f = read_f();
float g = f / 2.0f;
Это заставило меня задуматься: должен ли я всегда использовать соответствующие литералы для float, double, long и т. д.? Я обычно использую литералы типа int всякий раз, когда мне это удается, но я не уверен, что это хорошая идея.
Вы всегда должны явно указывать тип литерала, который вы собираетесь использовать. Это предотвратит проблемы, когда, например, такой код:
float foo = 9.0f;
float bar = foo / 2;
изменяется на следующее, обрезая результат:
int foo = 9;
float bar = foo / 2;
Это касается и параметров функций, когда у вас есть перегрузка и шаблоны.
Я знаю, что GCC имеет -Wconversion
но я не могу вспомнить все, что оно охватывает.
Для целочисленных значений, которые вписываются в int
Я обычно не готовлю их long
или же unsigned
так как там, как правило, гораздо меньше шансов для тонких ошибок.
Почти никогда не бывает абсолютно правильного ответа на вопрос «должен». Кто будет использовать этот код и для чего? Это актуально здесь. Но также, в частности для чего-либо, связанного с поплавками, полезно привыкнуть точно указывать нужные вам операции. float*float
сделано с одинарной точностью. все, что с двойным, делается с двойной точностью, 2
конвертируется в double, поэтому вы здесь указываете различные операции.
Лучший ответ здесь Что каждый компьютерщик должен знать об арифметике с плавающей точкой. Я бы сказал, что нет, нет простых ответов с плавающей запятой.