Обложка канала

C# 1001 notes

Регулярные короткие заметки по C# и .NET. Просто о сложном для каждого.

C# 1001 notes

8 лет назад
Открыть в
Литералы типа float и суффикс f в C#

Предполагаю, что тема числовых типов уже порядком вам поднадоела, однако, мне ещё есть чем с вами поделиться 🙂

Итак.. давайте проинициализируем несколько переменных типа float целочисленным и дробным значениями:

float f1 = 4;
float f2 = 4.2;


Есть ли на ваш взгляд здесь упущение?

С точки зрения разработчика - всё в порядке, тип float является типом с плавающей точкой и может хранить в себе оба указанных нами значения. Однако компилятор иного мнения, т.к. во второй строке мы получим ошибку компиляции:

Literal of type double cannot be implicitly converted to type 'float'.


Прежде чем я объясню почему так происходит, давайте разберём первую строку и вспомним правила приведения типов:

float f1 = 4;


В данном случае значение 4 является литералом типа int, который, в свою очередь, компилятор сумеет привести к типу float неявно (implicitly) ввиду отсутствия вероятности потери точности. Если этот момент вам не совсем понятен, я предлагаю вам вернуться к следующей заметке и вспомнить правила приведения типов.

Таким образом нам следует запомнить, что согласно спецификации языка C# тип любого целочисленного литерала определяется в зависимости от его значения (int, uint, long, ulong).

Отлично, надеюсь с этим разобрались. Так а что же со второй строкой? На самом деле- всё просто, и вот вторая вещь, которую нам стоит запомнить:

Любой дробный литерал в исходном коде является значением типа double, а значит мы пытаемся присвоить значение типа double переменной float.

Сделать это компилятор нам позволить не может, ввиду того, что такое приведение типов не может быть осуществлено неявно, а значит, мы должны явно (explicitly) дать понять, что нас это устраивает, следующим образом:

float f2 = (float)4.2;
float f3 = 4.2f;


В завершение мне осталось лишь отметить, что типы float и double являются двоичными типами с плавающей запятой, соответствующими стандарту IEEE 754, а значит значение 4.2 будет представлено как 4.19999980926513671875E0 для float (32 бита) и 4.20000000000000017763568394003E0 для double (64 бита).

💬 Если у вас после прочитанного ещё остались силы и интерес к данной теме, то я порекомендую вам замечательную статью Jon Skeet - Binary floating point and .NET и раздел Literals спецификации языка C# уже в качестве самостоятельного изучения 😉

#data_types