Decimal c что это
Как и во многих языках программирования, в C# есть своя система типов данных, которая используется для создания переменных. Тип данных определяет внутреннее представление данных, множество значений, которые может принимать объект, а также допустимые действия, которые можно применять над объектом.
В языке C# есть следующие базовые типы данных:
bool : хранит значение true или false (логические литералы). Представлен системным типом System.Boolean
byte : хранит целое число от 0 до 255 и занимает 1 байт. Представлен системным типом System.Byte
sbyte : хранит целое число от -128 до 127 и занимает 1 байт. Представлен системным типом System.SByte
short : хранит целое число от -32768 до 32767 и занимает 2 байта. Представлен системным типом System.Int16
ushort : хранит целое число от 0 до 65535 и занимает 2 байта. Представлен системным типом System.UInt16
int : хранит целое число от -2147483648 до 2147483647 и занимает 4 байта. Представлен системным типом System.Int32 . Все целочисленные литералы по умолчанию представляют значения типа int:
uint : хранит целое число от 0 до 4294967295 и занимает 4 байта. Представлен системным типом System.UInt32
long : хранит целое число от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 и занимает 8 байт. Представлен системным типом System.Int64
ulong : хранит целое число от 0 до 18 446 744 073 709 551 615 и занимает 8 байт. Представлен системным типом System.UInt64
float : хранит число с плавающей точкой от -3.4*10 38 до 3.4*10 38 и занимает 4 байта. Представлен системным типом System.Single
double : хранит число с плавающей точкой от ±5.0*10 -324 до ±1.7*10 308 и занимает 8 байта. Представлен системным типом System.Double
decimal : хранит десятичное дробное число. Если употребляется без десятичной запятой, имеет значение от ±1.0*10 -28 до ±7.9228*10 28 , может хранить 28 знаков после запятой и занимает 16 байт. Представлен системным типом System.Decimal
char : хранит одиночный символ в кодировке Unicode и занимает 2 байта. Представлен системным типом System.Char . Этому типу соответствуют символьные литералы:
string : хранит набор символов Unicode. Представлен системным типом System.String . Этому типу соответствуют строковые литералы.
object : может хранить значение любого типа данных и занимает 4 байта на 32-разрядной платформе и 8 байт на 64-разрядной платформе. Представлен системным типом System.Object , который является базовым для всех других типов и классов .NET.
Например, определим несколько переменных разных типов и выведем их значения на консоль:
Для вывода данных на консоль здесь применяется интерполяция: перед строкой ставится знак $ и после этого мы можем вводить в строку в фигурных скобках значения переменных. Консольный вывод программы:
Использование суффиксов
При присвоении значений надо иметь в виду следующую тонкость: все вещественные литералы (дробные числа) рассматриваются как значения типа double . И чтобы указать, что дробное число представляет тип float или тип decimal , необходимо к литералу добавлять суффикс: F/f — для float и M/m — для decimal.
Подобным образом все целочисленные литералы рассматриваются как значения типа int . Чтобы явным образом указать, что целочисленный литерал представляет значение типа uint, надо использовать суффикс U/u , для типа long — суффикс L/l , а для типа ulong — суффикс UL/ul :
Использование системных типов
Выше при перечислении всех базовых типов данных для каждого упоминался системный тип. Потому что название встроенного типа по сути представляет собой сокращенное обозначение системного типа. Например, следующие переменные будут эквивалентны по типу:
Неявная типизация
Ранее мы явным образом указывали тип переменных, например, int x; . И компилятор при запуске уже знал, что x хранит целочисленное значение.
Однако мы можем использовать и модель неявной типизации:
Для неявной типизации вместо названия типа данных используется ключевое слово var . Затем уже при компиляции компилятор сам выводит тип данных исходя из присвоенного значения. Так как по умолчанию все целочисленные значения рассматриваются как значения типа int , то поэтому в итоге переменная c будет иметь тип int . Аналогично переменной hello присваивается строка, поэтому эта переменная будет иметь тип string
Эти переменные подобны обычным, однако они имеют некоторые ограничения.
Во-первых, мы не можем сначала объявить неявно типизируемую переменную, а затем инициализировать:
Во-вторых, мы не можем указать в качестве значения неявно типизируемой переменной null :
Name already in use
docs / docs / csharp / language-reference / builtin-types / floating-point-numeric-types.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Floating-point numeric types (C# reference)
The floating-point numeric types represent real numbers. All floating-point numeric types are value types. They are also simple types and can be initialized with literals. All floating-point numeric types support arithmetic, comparison, and equality operators.
Characteristics of the floating-point types
C# supports the following predefined floating-point types:
In the preceding table, each C# type keyword from the leftmost column is an alias for the corresponding .NET type. They are interchangeable. For example, the following declarations declare variables of the same type:
The default value of each floating-point type is zero, 0 . Each of the floating-point types has the MinValue and MaxValue constants that provide the minimum and maximum finite value of that type. The float and double types also provide constants that represent not-a-number and infinity values. For example, the double type provides the following constants: xref:System.Double.NaN?displayProperty=nameWithType, xref:System.Double.NegativeInfinity?displayProperty=nameWithType, and xref:System.Double.PositiveInfinity?displayProperty=nameWithType.
The decimal type is appropriate when the required degree of precision is determined by the number of digits to the right of the decimal point. Such numbers are commonly used in financial applications, for currency amounts (for example, $1.00), interest rates (for example, 2.625%), and so forth. Even numbers that are precise to only one decimal digit are handled more accurately by the decimal type: 0.1, for example, can be exactly represented by a decimal instance, while there’s no double or float instance that exactly represents 0.1. Because of this difference in numeric types, unexpected rounding errors can occur in arithmetic calculations when you use double or float for decimal data. You can use double instead of decimal when optimizing performance is more important than ensuring accuracy. However, any difference in performance would go unnoticed by all but the most calculation-intensive applications. Another possible reason to avoid decimal is to minimize storage requirements. For example, ML.NET uses float because the difference between 4 bytes and 16 bytes adds up for very large data sets. For more information, see xref:System.Decimal?displayProperty=nameWithType.
You can mix integral types and the float and double types in an expression. In this case, integral types are implicitly converted to one of the floating-point types and, if necessary, the float type is implicitly converted to double . The expression is evaluated as follows:
- If there is double type in the expression, the expression evaluates to double , or to bool in relational and equality comparisons.
- If there is no double type in the expression, the expression evaluates to float , or to bool in relational and equality comparisons.
You can also mix integral types and the decimal type in an expression. In this case, integral types are implicitly converted to the decimal type and the expression evaluates to decimal , or to bool in relational and equality comparisons.
You cannot mix the decimal type with the float and double types in an expression. In this case, if you want to perform arithmetic, comparison, or equality operations, you must explicitly convert the operands either from or to the decimal type, as the following example shows:
You can use either standard numeric format strings or custom numeric format strings to format a floating-point value.
The type of a real literal is determined by its suffix as follows:
- The literal without suffix or with the d or D suffix is of type double
- The literal with the f or F suffix is of type float
- The literal with the m or M suffix is of type decimal
The following code demonstrates an example of each:
The preceding example also shows the use of _ as a digit separator. You can use the digit separator with all kinds of numeric literals.
You can also use scientific notation, that is, specify an exponent part of a real literal, as the following example shows:
There is only one implicit conversion between floating-point numeric types: from float to double . However, you can convert any floating-point type to any other floating-point type with the explicit cast. For more information, see Built-in numeric conversions.
C# language specification
For more information, see the following sections of the C# language specification:
Difference between decimal, float and double in .NET?
What is the difference between decimal , float and double in .NET?
When would someone use one of these?
18 Answers 18
float (the C# alias for System.Single ) and double (the C# alias for System.Double ) are floating binary point types. float is 32-bit; double is 64-bit. In other words, they represent a number like this:
The binary number and the location of the binary point are both encoded within the value.
decimal (the C# alias for System.Decimal ) is a floating decimal point type. In other words, they represent a number like this:
Again, the number and the location of the decimal point are both encoded within the value – that’s what makes decimal still a floating point type instead of a fixed point type.
The important thing to note is that humans are used to representing non-integers in a decimal form, and expect exact results in decimal representations; not all decimal numbers are exactly representable in binary floating point – 0.1, for example – so if you use a binary floating point value you’ll actually get an approximation to 0.1. You’ll still get approximations when using a floating decimal point as well – the result of dividing 1 by 3 can’t be exactly represented, for example.
As for what to use when:
For values which are "naturally exact decimals" it’s good to use decimal . This is usually suitable for any concepts invented by humans: financial values are the most obvious example, but there are others too. Consider the score given to divers or ice skaters, for example.
For values which are more artefacts of nature which can’t really be measured exactly anyway, float / double are more appropriate. For example, scientific data would usually be represented in this form. Here, the original values won’t be "decimally accurate" to start with, so it’s not important for the expected results to maintain the "decimal accuracy". Floating binary point types are much faster to work with than decimals.
C#: числовые типы (Numeric Types)
Среди целочисленных (integral) типов int и long используются наиболее часто. Остальные применяются для функциональной совместимости или когда действительно необходимы большие числа. Из реальных чисел, float и double , также называемые числами с плавающей точкой (floatingpoint types), обычно используются для научных вычислений. Тип decimal обычно используется в финансовых вычислениях, где необходима десятичная арифметика и высокая точность. Различия между double и decimal приведены в следующей таблице:
В связи с тем что типы float и double в своем внутреннем представлении являются двоичными, литералы с дробной частью (десятичные) не являются совсем точными:
По этой причине float и double лучше не использовать для финансовых вычислений, для которых лучше подходит тип decimal , десятичный в своей основе и поэтому более точный для дробных десятичных чисел.
Числовые литералы (Numeric Literals)
Целочисленные литералы (Integral literals) могут использовать десятичную (decimal) или шестнадцатеричную (hexadecimal) запись; шестнадцатеричная обозначается префиксом 0x (например, 0x7f = 127). Реально-числовые литералы также используют десятичную и шестнадцатеричную запись (например, 1E06 ).
По умолчанию, компилятор определяет тип числовых литералов по следующим критериям: если литерал содержит десятичную точку или знак экспоненты ( E ) — это double , в противном случае — это int , uint , long , или ulong .
Тип литерала также можно указать с помощью суффиксов, перечисленных в таблице выше. Суффикс ставиться сразу после литерала, например:
Необходимость в суффиксах U и L возникает крайне редко, т.к. почти всегда типы uint , long , и ulong могут быть либо выведены либо неявно преобразованы из int :
Суффикс D технически излишен, т.к. все литералы с десятичной точкой приводятся к double . Суффиксы F и M более полезны: они необходимы при написании дробных литералов типа float или decimal . Без суффикса подобные литералы будут считаться типом double , который не преобразуется скрыто к float или decimal .
Преобразование чисел
Скрытое преобразование целых чисел возможно только когда конечный тип вмещает все возможные значения исходного, в противном случае необходимо явное преобразование:
Преобразование реальных чисел. Число типа float может быть скрыто преобразовано к double , поскольку double способно вместить все возможные значения float . Обратное преобразование должно быть явным. Преобразование между decimal и другими реальными типами должно быть явным.
Преобразование между реальными и целыми числами. Преобразование целых чисел в реальные может быть скрытым, а вот обратное должно быть явным. Преобразование реальных чисел в целые происходит путем отсечения дробной части (без округления). Если необходимо преобразование с округлением, нужно использовать System.Convert класс. Важно помнить, что преобразование больших целых чисел в числа с плавающей точкой сохраняет их величину (magnitude, колличество цифр), но может привести к потере точности (precision):
Числовые операторы
Арифметические операторы
Арифметические операторы: + — * / % . Они применимы ко всем числовым типам, корме 8- и 16-битных целочисленных типов.
При делении целых чисел остаток всегда отсекается. При делении на переменную равную нулю возникает ошибка времени исполнения, а при делении на литерал или константу 0 — ошибка времени компиляции.
Оператор % возвращает остаток после деления.
Инкремент и декремент
Операторы инкремента ++ (Incremantal) и декремента — (Decremental) увеличивают и уменьшают (соответственно) числа на 1. Они могут идти до или после переменной, в зависимости от того, когда необходимо изменить переменную: до или после вычисления выражения:
Переполнение и оператор check
При выполнении арифметических операций с целыми числами возможно переполнение (Integral overflow) — ситуация, когда полученный результат превышает арифметические пределы типы. Как правило оно происходит тихо: никакие исключения не выбрасываются.
Оператор checked заставляет генерировать ошибку при переполнении (OverflowException). Он воздействует на выражения с операторами ++, —, — (унарный, обозначающий отрицательное число), +, -, *, / и операторами явного приведения между целочисленными типами. Применять его можно либо к одному выражению, либо к блоку:
В последнем случае, если для какого-либо выражения или блока необходимо отключить проверку переполнения, аналогичным способом необходимо использовать оператор unchecked .
Побитовые (поразрядные, bitwise) операторы
Каждый целочисленный тип может быть представлен в виде последовательности бит:
Битовые операторы применяются последовательно к каждой паре соответствующих битов своих операндов. Результатом будет значение того же типа, что и операнды, каждый бит которого есть результат применения соответствующего побитового оператора.
К побитовым операторам относятся:
- И — & — устанавливает (в значение 1) только те биты, которые установлены (имеют значение 1) в обоих операндах, остальные биты выключаются (устанавливаются в 0)
- ИЛИ — | — устанавливает те биты которые установлены либо в одном, либо в другом операнде
- ИСКЛЮЧАЮЩЕЕ ИЛИ — ^ — устанавливает только те биты, которые установлены либо в одном, либо в другом операнде, но не в обоих одновременно
- ОТРИЦАНИЕ —
a ) ; // 11111010 == 250
Операции с 8-битные и 16-битные целыми числами
8-битные и 16-битные целые числа ( byte , sbyte , short , ushort ) не имеют собственных операторов, поэтому C# неявно преобразовывает их в большие типы при необходимости. В связи с этим при компиляции может возникнуть ошибка, если результату попытаться снова назначить младший тип:
В этом примере x и y скрыто преобразуются в int , чтоб над ними можно было выполнить сложение. Результат в связи с этим тоже будет иметь тип int , который не может быть скрыто преобразован обратно в short (т.к. это может привести к потере данных). Чтобы избежать ошибки, необходимо использовать явное приведение к типу:
Операции над числами с плавающей точкой
Типы с плавающей точкой (в отличие от целочисленных) имеют ряд специальных значений, которые ведут себя по особенному в ряде случаев. Этими специальными значениями являются:
- NaN (Not a Number)
- +∞
- –∞
- –0
Деление ненулевого значения на ноль дает бесконечность:
Деление ноль на ноль и вычитание бесконечности из бесконечности дает NaN :
При использовании оператора сравнения == , значение NaN никогда не будет равно никакому другому значению, в том числе другому значению NaN . Для проверки значения на равенство NaN нужно использовать методы float.IsNaN и double.IsNaN :
Однако, при использовании метода object.Equals два NaN значения будут равны:
Преобразование чисел в строку, форматные строки
Числовые типы определяют экземплярный метод ToString , позволяющий преобразовать число в строку. В качестве дополнительного параметра метод может принимать форматные строки. Подробно этот метод и форматные строки рассмотрены в разделе, посвященном форматированию и преобразованию строк. Ниже будут перечислены стандартные и специальные форматные строки для чисел.
Стандартные форматные строки для чисел
Символ | Значение | Пример | Результат | Примечание |
---|---|---|---|---|
G или g | Общий (general) формат | 1.2345, «G» 0.00001, «G» 0.00001, «g» 1.2345, «G3» 12345, «G3» |
1.2345 1E-05 1e-05 1.23 1.23E04 |
Перключается на экспоненциальную запись для очень маленьких и больших чисел. Цифра ограничивает точность (количество цифр) |
F | Формат с фиксированной точкой | 2345.678, «F2» 2345.6, «F2» |
2345.68 2345.60 |
Цифра указывает сколько знаков оставить после запятой |
N | Формат с фиксированной точкой и разделителем групп | 2345.678, «N2» 2345.6, «N2» |
2,345.68 2,345.60 |
Тоже самое что и F, но с разделением групп (тысяч) |
D | Заполнение ведущими нулями | 123, «D5» 123, «D1» |
00123 123 |
Только для целых типов. Цифра указывает до какой длины дополнять, усечение не происходит |
E или e | Экспоненциальная запись | 56789, «E» 56789, «e» 56789, «E2» |
5.678900E+004 5.678900e+004 5.68E+004 |
Цифра указывает точность (по умолчанию — 6) |
C | Денежное значение | 1.2, «C» 1.2, «C4» |
$1.20 $1.2000 |
Цифра указывает количество знаков после запятой |
P | Процент | .503, «P» .503, «P0» |
50.30 % 50 % |
Цифра указывает количество знаков после запятой |
X или x | Шестнадцатеричный формат | 47, «X» 47, «x» 47, «X4» |
2F 2f 002F |
X — верхний регистр, x — нижний регистр |
R | Округление | 1f / 3f, «R» | 0.333333343 |
Указание иной форматной строки, пустой строки или null эквивалентно «G».
Специальные форматные строки для чисел
Символ | Значение | Пример | Результат | Примечание |
---|---|---|---|---|
# | Заполнитель для цифр | 12.345, «.##» 12.345, «.####» |
12.35 12.345 |
|
0 | Заполнитель для нуля | 12.345, «.00» 12.345, «.0000» 99, «000.00» |
12.35 12.3500 099.00 |
|
. | Десятичная точка | |||
, | Разделитель групп | 1234, «#,###,###» 1234, «0,000,000» |
1,234 0,001,234 |
|
, | Коэффициент | 1000000, «#,» 1000000, «#,,» |
1000 1 |
|
% | Процентная запись | 0.6, «00%» | 60% | |
E0, e0, E+0, e+0 E-0, e-0 |
Экспоненциальная запись | 1234, «0E0» 1234, «0E+0» 1234, «0.00E00» 1234, «0.00e00» |
1E3 1E+3 1.23E03 1.23e03 |
|
/ | Скобка для литерального символа | 50, @»\#0″ | #50 | Используется в сочетании с префиксом @ в строках или можно применять // |
‘xx»xx’ | Скобка для литеральной строки | 50, «0 ‘…’» | 50 … | |
; | Разделитель секций | 15, «#;(#);zero» −5, «#;(#);zero» 0, «#;(#);zero» |
15 (5) zero |
|
другой символ | Литерал | 35.2, «$0 . 00c» | $35 . 20c |
Преобразование строки в число, NumberStyles
Преобразование строки в число можно осуществить с помощью статических методов Parse и TryParse . Подробно эти методы рассмотрены в разделе, посвященном форматированию и преобразованию строк.
Оба метода могут принимать enum NumberStyles , определяющий как строка читается при преобразовании в числовой тип (они позволяют указывать такие аспекты, как могут ли встречаться во входной строке круглые скобки или символ валюты):