Числовые типы с плавающей запятой (справочник по C#)
Числовые типы с плавающей запятой представляют действительные числа. Все числовые типы с плавающей запятой являются типами значений. Они также представляют собой простые типы и могут быть инициализированы литералами. Все числовые типы с плавающей запятой поддерживают арифметические операторы, а также операторы сравнения и равенства.
Характеристики типов с плавающей запятой
C# поддерживает следующие предварительно определенные типы с плавающей запятой:
Ключевое слово или тип C# | Приблизительный диапазон значений | Точность | Размер | Тип .NET |
---|---|---|---|---|
float | От ±1,5 x 10 −45 до ±3,4 x 10 38 | 6–9 цифр | 4 байта | System.Single |
double | от ±5,0 × 10 −324 до ±1,7 × 10 308 | 15–17 цифр | 8 байт | System.Double |
decimal | от ±1,0 x 10 -28 до ±7,9228 x 10 28 | 28-29 знаков | 16 байт | System.Decimal |
В приведенной выше таблице каждый тип ключевого слова C# из крайнего левого столбца является псевдонимом для соответствующего типа .NET. Они взаимозаменяемые. Например, следующие объявления объявляют переменные одного типа:
double a = 12.3; System.Double b = 12.3;
По умолчанию все типы с плавающей запятой имеют значение 0 . Все типы с плавающей запятой имеют константы MinValue и MaxValue с минимальным и максимальными итоговыми значениями этого типа. Типы float и double также предоставляют константы, обозначающие бесконечные и нечисловые значения. Например, тип double предоставляет следующие константы: Double.NaN, Double.NegativeInfinity и Double.PositiveInfinity.
Тип decimal подходит, если требуемая степень точности определяется числом цифр справа от десятичной запятой. Такие числа обычно используются в финансовых приложениях для денежных сумм (например, 1,00 долл. США), процентных ставок (например, 2,625 %) и т. д. Даже числа, точные только к одной десятичной цифре, обрабатываются более точно decimal типом: 0,1, например, может быть точно представлен decimal экземпляром, а double float экземпляр не представляет 0,1. Из-за этой разницы в числовых типах в арифметических вычислениях могут возникать непредвиденные ошибки округления при использовании double или float для десятичных данных. Вы можете использовать double вместо decimal , если оптимизация производительности важнее, чем обеспечение точности. Но любая разница в производительности останется незамеченной для всех приложений, кроме самых требовательных к вычислениям. Еще одна возможная причина, по которой следует избегать decimal , — это минимальные требования к хранилищу. Например, ML.NET использует float , так как разница между 4 байтами и 16 байтами суммируется для очень больших наборов данных. Дополнительные сведения см. в разделе System.Decimal.
В одном и том же выражении можно сочетать и целочисленные типы, и типы float и double . В этом случае целочисленные типы неявно преобразуются в один из типов с плавающей запятой. При необходимости тип float неявно преобразуется в double . Выражение вычисляется следующим образом.
- Если в выражении есть тип double , оно оценивается как double или bool в реляционных сравнениях или сравнениях на равенство.
- Если в выражении нет типа double , оно оценивается как float или bool в реляционных сравнениях или сравнениях на равенство.
Можно также смешивать целочисленные типы и тип decimal в выражении. В этом случае целочисленные типы неявно преобразуются в тип decimal , а выражение вычисляется как decimal или bool в реляционных сравнениях и сравнениях на равенство.
Тип decimal нельзя смешивать с типами float и double в выражении. В этом случае, если требуется выполнить арифметические операции или операции сравнения или равенства, необходимо явно преобразовать операнды из типа или в тип decimal , как показано в следующем примере:
double a = 1.0; decimal b = 2.1m; Console.WriteLine(a + (double)b); Console.WriteLine((decimal)a + b);
Можно использовать строки стандартных числовых форматов или строки пользовательских числовых форматов для форматирования значения с плавающей запятой.
Вещественные литералы
Тип реального литерала определяется его суффиксом следующим образом:
- Литерал без суффикса или с суффиксом d или D имеет тип double .
- Литерал с суффиксом f или F имеет тип float .
- Литерал с суффиксом m или M имеет тип decimal .
В приведенном ниже коде показан пример каждого из них.
double d = 3D; d = 4d; d = 3.934_001; float f = 3_000.5F; f = 5.4f; decimal myMoney = 3_000.5m; myMoney = 400.75M;
В предыдущем примере также показано использование _ в качестве разделителя цифр. Цифровой разделитель можно использовать со всеми видами числовых литералов.
Можно также использовать экспоненциальное представление, то есть указать экспоненту вещественного литерала, как показано в следующем примере:
double d = 0.42e2; Console.WriteLine(d); // output 42 float f = 134.45E-2f; Console.WriteLine(f); // output: 1.3445 decimal m = 1.5E6m; Console.WriteLine(m); // output: 1500000
Преобразования
Существует только одно неявное преобразование между числовыми типами с плавающей запятой: из float в double . Однако можно преобразовать любой тип с плавающей запятой в любой другой тип с плавающей запятой с помощьюявного приведения. Для получения дополнительной информации см. статью Встроенные числовые преобразования.
Спецификация языка C#
Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:
- Типы с плавающей запятой
- Тип decimal
- Вещественные литералы
См. также
- справочник по C#
- Типы значений
- Целочисленные типы
- Строки стандартных числовых форматов
- Числовые значения в .NET
- System.Numerics.Complex
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Встроенные типы (C++)
Встроенные типы (также называемые фундаментальными типами) задаются стандартом языка C++ и встроены в компилятор. Встроенные типы не определены в файле заголовка. Встроенные типы делятся на три основные категории: целочисленные, с плавающей запятой и void. Целочисленные типы представляют целые числа. Типы с плавающей запятой могут указывать значения, которые могут содержать дробные части. Большинство встроенных типов рассматриваются как отдельные типы компилятором. Однако некоторые типы являются синонимами или рассматриваются как эквивалентные типы компилятором.
Тип void
Тип void описывает пустой набор значений. Переменная типа void не может быть указана. Тип void используется в основном для объявления функций, которые не возвращают значения или объявляют универсальные указатели на нетипизированные или произвольные типизированные данные. Любое выражение можно явно преобразовать или привести к типу void . Однако такие выражения можно использовать только в следующих операторах и операндах:
- в операторе выражения (Дополнительные сведения см. в разделе Выражения.)
- в левом операнде оператора запятой (Дополнительные сведения см. в разделе Оператор запятой.)
- во втором и третьем операндах условного оператора ( ? : ). (Дополнительные сведения см. в разделе Выражения с условным оператором.)
std::nullptr_t
Ключевое слово nullptr является константой std::nullptr_t типа null-указателя, которая преобразуется в любой необработанный тип указателя. Дополнительные сведения см. в разделе nullptr .
Тип Boolean
Тип bool может иметь значения true и false . Размер bool типа зависит от реализации. Дополнительные сведения о реализации см. в разделе «Размеры встроенных типов «.
Символьные типы
Тип char — это тип представления символов, который эффективно кодирует элементы базового набора символов выполнения. Компилятор C++ обрабатывает переменные типа char , signed char и unsigned char как переменные разных типов.
Корпорация Майкрософт: переменные типа char по умолчанию действуют как int будто из типа signed char , если /J только не используется параметр компиляции. В этом случае они рассматриваются как тип unsigned char и повышаются до int без расширения знака.
Переменная типа wchar_t — это расширенный или многобайтовый тип символов. L Используйте префикс перед символом или строковым литералом, чтобы указать тип расширенных символов.
Корпорация Майкрософт: по умолчанию wchar_t — это собственный тип, но вы можете использовать /Zc:wchar_t- его для unsigned short определения wchar_t типа. __wchar_t — синоним для машинного типа wchar_t для систем Майкрософт.
Тип char8_t используется для представления символов UTF-8. Он имеет то же представление, что unsigned char и , но рассматривается как отдельный тип компилятором. Тип char8_t новый в C++20. Корпорация Майкрософт: для использования char8_t требуется /std:c++20 параметр компилятора или более поздней версии (например /std:c++latest , ).
Тип char16_t используется для представления символов UTF-16. Оно должно быть достаточно большим, чтобы представить любую единицу кода UTF-16. Он рассматривается как отдельный тип компилятором.
Тип char32_t используется для представления символов UTF-32. Оно должно быть достаточно большим, чтобы представить любую единицу кода UTF-32. Он рассматривается как отдельный тип компилятором.
Типы с плавающей запятой
Типы с плавающей запятой используют представление IEEE-754 для обеспечения приближения дробных значений по широкому диапазону величин. В следующей таблице перечислены типы с плавающей запятой в C++ и относительные ограничения на размеры типов с плавающей запятой. Эти ограничения являются обязательными стандартом C++ и не зависят от реализации Майкрософт. Абсолютный размер встроенных типов с плавающей запятой не указан в стандарте.
Тип | Содержимое |
---|---|
float | Тип float является наименьшим типом с плавающей запятой в C++. |
double | double — это тип с плавающей запятой, размер которого больше или равен размеру типа float , но меньше или равен размеру типа long double . |
long double | long double — это тип с плавающей запятой, размер которого больше или равен размеру типа double . |
Корпорация Майкрософт: представление long double и double идентично. long double Однако и double рассматриваются как отдельные типы компилятором. Компилятор Microsoft C++ использует представления с плавающей запятой 4 и 8-байтов IEEE-754. Дополнительные сведения см. в представлении с плавающей запятой IEEE.
Целочисленные типы
Тип int — базовый целочисленный тип по умолчанию. Он может представлять все целые числа по определенному диапазону реализации.
Целочисленное представление со знаком — это одно из них, которое может содержать как положительные, так и отрицательные значения. Он используется по умолчанию или signed при наличии модификатора ключевое слово. Модификатор unsigned ключевое слово указывает неподписаемое представление, которое может содержать только неотрицательных значений.
Модификатор размера указывает ширину в битах используемого целочисленного представления. Язык поддерживает short и long long long модификаторы. Тип short должен быть не менее 16 бит ширины. Тип long должен быть не менее 32 битов ширины. Тип должен быть по крайней long long мере 64-разрядным. Стандарт задает связь размера между целочисленными типами:
Реализация должна поддерживать как минимальные требования к размеру, так и отношение размера для каждого типа. Однако фактические размеры могут отличаться между реализацией. Дополнительные сведения о реализации см. в разделе «Размеры встроенных типов «.
Ключевое слово int могут быть опущены при signed unsigned указании модификаторов размера или размера. Модификаторы и int тип, если они присутствуют, могут отображаться в любом порядке. Например, short unsigned и unsigned int short ссылаться на тот же тип.
Синонимы целочисленного типа
Следующие группы типов считаются синонимами компилятора:
Типы целых чисел, зависящие от Майкрософт, включают определенные ширины __int8 , __int16 __int32 а также __int64 типы. Эти типы могут использовать signed модификаторы и unsigned модификаторы. Тип данных __int8 аналогичен типу char , __int16 — типу short , __int32 — типу int , а __int64 — типу long long .
Размеры встроенных типов
Большинство встроенных типов имеют определенные реализацией размеры. В следующей таблице перечислены объем хранилища, необходимый для встроенных типов в Microsoft C++. В частности, long 4 байта даже в 64-разрядных операционных системах.
Тип | Size |
---|---|
bool , char , char8_t , unsigned char , signed char , __int8 | 1 байт |
char16_t , __int16 , short , unsigned short , wchar_t , __wchar_t | 2 байта |
char32_t , float , __int32 , int , unsigned int , long , unsigned long | 4 байта |
double , __int64 , long double , long long , unsigned long long | 8 байт |
Сведения о диапазоне типов данных см. в сводке по диапазону значений каждого типа.
Дополнительные сведения о преобразовании типов см. в разделе «Стандартные преобразования».
В чем разница между float и double в Java?
Какая еще есть разница между типами данных float и double или я что-то в упор не вижу?
Отслеживать
14.3k 1 1 золотой знак 21 21 серебряный знак 31 31 бронзовый знак
задан 18 июл 2017 в 21:19
Yuri Migushin Yuri Migushin
61 1 1 серебряный знак 7 7 бронзовых знаков
Вставляйте код прямо в сообщение (в виде кода), а не ссылайтесь на внешние ресурсы. Сообщения должны быть самодостаточными, ссылки могут служить только дополнением.
18 июл 2017 в 22:46
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Принципиальный нюанс здесь в том, что вы оперируете десятичными числами, а float и double — бинарные. Те числа, которые вы делите и получаете в результате, непредставимы в бинарной системе счисления без периодичных дробей. Подробнее:
То, что вы наблюдаете — это не округления и обрубания, а попытки компьютера впихать невпихуемое и сделать вид, что на самом деле всё в порядке. Так как количество битов у мантиссы и экспоненты типов float и double разная, то «округления» и «обрубания» будут происходить с вашей точки зрения «непредсказуемо». Эта ситуация усугубляется ещё и тем, что точность вычислений на совести процессора, который, вообще говоря, не обязан выдавать точность до последнего знака. На другом компьютере вы можете увидеть другие результаты — если не включите специальный «предсказуемый» режим, который медленнее. Но даже в этом случае вы получите только одинаковые, но «непредсказуемые» результаты на разных компьютерах.
Когда работаете с float и double, примите как данность, что они всегда с погрешностью.
Чем double отличается от float
На 32-разрядной платформе ARM, в среде разработки IAR EWB for ARM применены следующие типы float, double и long double.
float — 32-битное число с плавающей точкой. Диапазон чисел от ±1.18E-38 до ±3.39E+38, 7 десятичных разрядов, 8 бит показателя степени (экспонента) и 23 бита основания степени (мантисса).
double — 64-битное число с плавающей точкой. Диапазон чисел от ±2.23E-308 to ±1.79E+308, 15 десятичных разрядов, 11 бит показателя степени (экспонента) и 52 бита основания степени (мантисса).
long double — абсолютно то же самое, что и double.
Операции с числами в формате с плавающей точкой весьма неэффективны по затратам кода, памяти и процессорного времени, поэтому таких чисел нужно по возможности избегать, или хотя бы использовать float вместо double.
Информация получена из документа справки «IAR C/C++ Development Guide» EWARM_DevelopmentGuide.ENU.pdf, раздел «FLOATING-POINT TYPES».
[См. также]
1. Описание стандартных функций < cmath >(math.h) site:cplusplus.com .
2. Как избавиться от чисел с плавающей точкой.