Почему при объявлении поплавков требуется "f"?


пример:

float timeRemaining = 0.58f;

почему f требуется в конце числа?

3 65

3 ответа:

ваше объявление поплавка содержит две части:

  1. он объявляет, что переменная timeRemaining типа float.
  2. присваивается значение 0.58 к этой переменной.

проблема возникает в части 2.

правая сторона оценивается сама по себе. Согласно спецификации C#, число, содержащее десятичную точку, которая не имеет суффикса, интерпретируется как double.

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

причина в том, что значение, используемое компилятором, на самом деле не 0.58, а значение с плавающей запятой, ближайшее к 0.58, которое равно 0.579999999999978655962351581366... ибо double и точно 0,579999946057796478271484375 ибо float.

строго говоря,f не требуется. Вы можете избежать необходимости использовать f суффикс путем приведения значения к float:

float timeRemaining = (float)0.58;

потому что есть несколько числовых типов, которые компилятор может использовать для представления значения 0.58:float,double и decimal. Если вы не в порядке с компилятором, выбирающим его для вас, вы должны устранить неоднозначность.

документация double утверждает, что если вы не укажете тип самостоятельно, компилятор всегда выбирает double как тип любого реального числового литерала:

By по умолчанию, реальный числовой литерал в правой части назначения оператор обработан как двойник. Однако, если вы хотите целое число чтобы быть обработанным как двойной, используйте суффикс d или D.

добавления суффикса f создает float; суффикс d создает double; суффикс m создает decimal. Все они также работают в верхнем регистре.

однако этого все еще недостаточно, чтобы объяснить, почему это не так компиляция:

float timeRemaining = 0.58;

недостающая половина ответа заключается в том, что преобразование double0.58 до floattimeRemaining потенциально теряет информацию, поэтому компилятор отказывается выполнять его беспрекословно. Если вы добавляете явное приведение, преобразование выполняется; если вы добавляете f суффикс тогда никакого преобразования не потребуется. В обоих случаях код будет компилироваться.

проблема в том, что .NET, чтобы позволить некоторым типам неявных операций выполняться с участием float и double, необходимо либо явно указать, что должно произойти во всех сценариях, включающих смешанные операнды, либо разрешить неявные преобразования между типами, которые будут выполняться только в одном направлении; Microsoft решила следовать примеру Java в разрешении направления, которое иногда способствует точности, но часто жертвует корректностью и обычно создает перебранка.

практически во всех случаях, принимая double значение, которое ближе всего к определенному числовому количеству и присваивает его float даст float значение, которое ближе всего к тем же количество. Есть несколько угловых случаев, таких как значение 9,007,199,791,611,905; лучший float представление будет 9,007,200,328,482,816 (который выключен на 536,870,911), но кастинг лучший double представление (т. е. 9,007,199,791,611,904) в float дает 9,007,199,254,740,992 (который выключен на 536,870,913). В общем, тем не менее, преобразование лучших double представление некоторой величины в float либо даст наилучший результат float представление, или одно из двух представлений, которые по сути одинаково хороши.

обратите внимание, что это желательное поведение применяется даже в крайних случаях; например, лучший float представление для количества 10^308 соответствует float представление достигается путем преобразования лучших double представление этой величины. Точно так же, лучший float представление 10^309 матчей float представление достигается путем преобразования лучших double представление этой величины.

к сожалению, преобразования в направлении, которое не требует явного приведения, редко так точно. Преобразование лучших float представление значения!--1--> редко даст что-то особенно близкое к лучшему double представление это значение, а в некоторых случаях результат может быть отключен на сотни порядков (например, преобразование лучшего float представление от 10^40 до double даст значение, которое сравнивается больше, чем лучший double представление 10^300.

увы, правила преобразования таковы, каковы они есть, поэтому приходится жить с использованием глупых типов и суффиксов при преобразовании значений в" безопасном " направлении и быть осторожным с неявными типами в опасном направлении, которые будут часто дают фиктивные результаты.