Typy liczb zmiennoprzecinkowych (dokumentacja C#)
Typy liczb zmiennoprzecinkowe reprezentują liczby rzeczywiste. Wszystkie typy liczb zmiennoprzecinkowe to typy wartości . Są one również proste typy i mogą być inicjowane za pomocą literałów . Wszystkie typy zmiennoprzecinkowe liczb obsługują operatory arytmetyczne , porównania i równości .
Charakterystyka typów zmiennoprzecinkowych
Język C# obsługuje następujące wstępnie zdefiniowane typy zmiennoprzecinkowe:
Typ/słowo kluczowe języka C# | Przybliżony zakres | Precyzja | Rozmiar | Typ platformy .NET |
---|---|---|---|---|
float |
±1,5 x 10−45 do ±3,4 x 1038 | ~6–9 cyfr | 4 bajty | System.Single |
double |
±5.0 × 10−324 do ±1.7 × 10308 | ~15–17 cyfr | 8 bajtów | System.Double |
decimal |
±1.0 x 10-28 do ±7.9228 x 1028 | 28–29 cyfr | 16 bajtów | System.Decimal |
W poprzedniej tabeli każde słowo kluczowe typu C# z lewej kolumny jest aliasem odpowiadającego mu typu .NET. Są one zamienne. Na przykład następujące deklaracje deklarują zmienne tego samego typu:
double a = 12.3;
System.Double b = 12.3;
Wartość domyślna każdego typu zmiennoprzecinkowego to zero, 0
. Każdy z typów zmiennoprzecinkowych ma stałe MinValue
i MaxValue
, które określają minimalną i maksymalną skończoną wartość możliwą dla tego typu. Typy float
i double
zapewniają również stałe reprezentujące wartości nieliczne i nieskończone. Na przykład typ double
zawiera następujące stałe: Double.NaN, Double.NegativeInfinityi Double.PositiveInfinity.
Typ decimal
jest odpowiedni, gdy wymagany stopień dokładności jest określany przez liczbę cyfr po prawej stronie przecinka dziesiętnego. Takie liczby są często używane w aplikacjach finansowych, w przypadku kwot walutowych (na przykład 1,00 USD), stóp procentowych (na przykład 2,625%), itd. Nawet liczby dokładne dla tylko jednej cyfry dziesiętnej są obsługiwane dokładniej przez typ decimal
: 0,1, na przykład może być dokładnie reprezentowane przez wystąpienie decimal
, podczas gdy nie ma double
lub float
wystąpienia, które dokładnie reprezentuje 0,1. Ze względu na tę różnicę w typach liczbowych mogą wystąpić nieoczekiwane błędy zaokrąglania w obliczeniach arytmetycznych podczas używania double
lub float
dla danych dziesiętnych. Można użyć double
zamiast decimal
, kiedy podczas optymalizacji wydajności jest ważniejsze niż zapewnienie dokładności. Jednak każda różnica w wydajności byłaby niezauważona dla wszystkich, z wyjątkiem najbardziej intensywnie obliczeniowych aplikacji. Innym możliwym powodem uniknięcia decimal
jest zminimalizowanie wymagań dotyczących magazynu. Na przykład ML.NET używa float
, ponieważ różnica między 4 bajtami a 16 bajtami sumuje się w przypadku bardzo dużych zestawów danych. Aby uzyskać więcej informacji, zobacz System.Decimal.
W wyrażeniu można mieszać typy całkowite oraz typy, float
i double
. W takim przypadku typy całkowite są niejawnie konwertowane na jeden z typów zmiennoprzecinkowych, a w razie potrzeby typ float
jest niejawnie konwertowany na double
. Wyrażenie jest oceniane w następujący sposób:
- Jeśli w wyrażeniu znajduje się typ
double
, przyjmuje wartośćdouble
lubbool
w porównaniach relacyjnych i równości. - Jeśli w wyrażeniu nie ma typu
double
, wyrażenie przyjmuje wartośćfloat
lub w porównaniach relacyjnych i równości dobool
.
Można również mieszać typy całkowite i typ decimal
w wyrażeniu. W takim przypadku typy całkowite są niejawnie konwertowane na typ decimal
, a wyrażenie uzyskuje wartość decimal
, a w porównaniach relacyjnych i równościowych przyjmuje wartość bool
.
Nie można mieszać typu decimal
z typami float
i double
w wyrażeniu. W takim przypadku, jeśli chcesz wykonać operacje arytmetyczne, porównania lub równości, musisz jawnie przekonwertować operandy z lub na typ decimal
, jak pokazano w poniższym przykładzie:
double a = 1.0;
decimal b = 2.1m;
Console.WriteLine(a + (double)b);
Console.WriteLine((decimal)a + b);
Aby sformatować wartość zmiennoprzecinkową, można użyć standardowych ciągów formatu liczbowego lub niestandardowych ciągów formatu liczbowego.
Literały rzeczywiste
Typ literału rzeczywistego jest określany przez jego sufiks w następujący sposób:
- Literał bez sufiksu lub z sufiksem
d
lubD
jest typudouble
- Literał z sufiksem
f
lubF
jest typufloat
- Literał z sufiksem
m
lubM
jest typudecimal
Poniższy kod przedstawia przykład każdego z nich:
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;
W poprzednim przykładzie pokazano również użycie _
jako separatora cyfr . Separatora cyfr można używać ze wszystkimi rodzajami literałów liczbowych.
Możesz również użyć notacji naukowej, czyli określić część wykładniczą literału liczby rzeczywistej, jak pokazano w poniższym przykładzie.
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
Konwersje
Istnieje tylko jedna niejawna konwersja między typami liczb zmiennoprzecinkowych: od float
do double
. Można jednak przekonwertować dowolny typ zmiennoprzecinkowy na dowolny inny typ zmiennoprzecinkowy przy użyciu jawnego rzutowania. Aby uzyskać więcej informacji, zobacz wbudowane konwersje liczbowe.
Specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz następujące sekcje specyfikacji języka C#:
- typy zmiennoprzecinkowe
- typ dziesiętny
- Literały rzeczywiste