Почему при объявлении поплавков требуется "f"?
пример:
float timeRemaining = 0.58f;
почему f
требуется в конце числа?
3 ответа:
ваше объявление поплавка содержит две части:
- он объявляет, что переменная
timeRemaining
типаfloat
.- присваивается значение
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;
недостающая половина ответа заключается в том, что преобразование
double
0.58
доfloat
timeRemaining
потенциально теряет информацию, поэтому компилятор отказывается выполнять его беспрекословно. Если вы добавляете явное приведение, преобразование выполняется; если вы добавляете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.увы, правила преобразования таковы, каковы они есть, поэтому приходится жить с использованием глупых типов и суффиксов при преобразовании значений в" безопасном " направлении и быть осторожным с неявными типами в опасном направлении, которые будут часто дают фиктивные результаты.